From 2c3d3b618503da4f483604a9d4c9761766d55b4d Mon Sep 17 00:00:00 2001 From: Konsta Date: Thu, 30 Apr 2026 16:13:20 +0300 Subject: [PATCH] android: Add soong blueprint makefiles generated by ninja-to-soong --- Android.bp | 409 +++ meson_generated/config.h | 31 + .../include/libcamera/control_ids.h | 513 +++ meson_generated/include/libcamera/formats.h | 124 + .../include/libcamera/internal/tracepoints.h | 237 ++ .../include/libcamera/ipa/core.mojom-module | Bin 0 -> 10199 bytes .../libcamera/ipa/core_ipa_interface.h | 163 + .../libcamera/ipa/core_ipa_serializer.h | 1046 +++++++ .../libcamera/ipa/raspberrypi.mojom-module | Bin 0 -> 32546 bytes .../libcamera/ipa/raspberrypi_ipa_interface.h | 377 +++ .../libcamera/ipa/raspberrypi_ipa_proxy.h | 239 ++ .../ipa/raspberrypi_ipa_serializer.h | 1188 +++++++ meson_generated/include/libcamera/libcamera.h | 28 + .../include/libcamera/property_ids.h | 99 + meson_generated/src/ipa-priv-key.pem | 28 + meson_generated/src/libcamera/control_ids.cpp | 2761 +++++++++++++++++ meson_generated/src/libcamera/glsl_shaders.h | 1124 +++++++ meson_generated/src/libcamera/ipa_pub_key.cpp | 58 + .../src/libcamera/property_ids.cpp | 872 ++++++ .../libcamera/proxy/raspberrypi_ipa_proxy.cpp | 683 ++++ meson_generated/src/libcamera/version.cpp | 16 + .../utils/codegen/ipc/libcamera_templates.zip | Bin 0 -> 131503 bytes 22 files changed, 9996 insertions(+) create mode 100644 Android.bp create mode 100644 meson_generated/config.h create mode 100644 meson_generated/include/libcamera/control_ids.h create mode 100644 meson_generated/include/libcamera/formats.h create mode 100644 meson_generated/include/libcamera/internal/tracepoints.h create mode 100644 meson_generated/include/libcamera/ipa/core.mojom-module create mode 100644 meson_generated/include/libcamera/ipa/core_ipa_interface.h create mode 100644 meson_generated/include/libcamera/ipa/core_ipa_serializer.h create mode 100644 meson_generated/include/libcamera/ipa/raspberrypi.mojom-module create mode 100644 meson_generated/include/libcamera/ipa/raspberrypi_ipa_interface.h create mode 100644 meson_generated/include/libcamera/ipa/raspberrypi_ipa_proxy.h create mode 100644 meson_generated/include/libcamera/ipa/raspberrypi_ipa_serializer.h create mode 100644 meson_generated/include/libcamera/libcamera.h create mode 100644 meson_generated/include/libcamera/property_ids.h create mode 100644 meson_generated/src/ipa-priv-key.pem create mode 100644 meson_generated/src/libcamera/control_ids.cpp create mode 100644 meson_generated/src/libcamera/glsl_shaders.h create mode 100644 meson_generated/src/libcamera/ipa_pub_key.cpp create mode 100644 meson_generated/src/libcamera/property_ids.cpp create mode 100644 meson_generated/src/libcamera/proxy/raspberrypi_ipa_proxy.cpp create mode 100644 meson_generated/src/libcamera/version.cpp create mode 100644 meson_generated/utils/codegen/ipc/libcamera_templates.zip diff --git a/Android.bp b/Android.bp new file mode 100644 index 00000000..83043a5e --- /dev/null +++ b/Android.bp @@ -0,0 +1,409 @@ +// +// This file has been auto-generated by ninja-to-soong +// +// ****************************** +// *** DO NOT MODIFY MANUALLY *** +// ****************************** +// +// https://github.com/rjodinchr/ninja-to-soong +// + +package { + default_visibility: ["//visibility:public"], + default_applicable_licenses: ["libcamera_rpi_licenses"], +} + +license { + name: "libcamera_rpi_licenses", + visibility: [":__subpackages__"], + license_kinds: ["SPDX-license-identifier-LGPL-2.1-or-later"], +} + +cc_library_shared { + name: "libcamera", + srcs: [ + "meson_generated/src/libcamera/*.cpp", + "meson_generated/src/libcamera/proxy/raspberrypi_ipa_proxy.cpp", + "src/libcamera/bayer_format.cpp", + "src/libcamera/byte_stream_buffer.cpp", + "src/libcamera/camera.cpp", + "src/libcamera/camera_controls.cpp", + "src/libcamera/camera_lens.cpp", + "src/libcamera/camera_manager.cpp", + "src/libcamera/clock_recovery.cpp", + "src/libcamera/color_space.cpp", + "src/libcamera/control_serializer.cpp", + "src/libcamera/control_validator.cpp", + "src/libcamera/controls.cpp", + "src/libcamera/converter.cpp", + "src/libcamera/converter/*.cpp", + "src/libcamera/debug_controls.cpp", + "src/libcamera/delayed_controls.cpp", + "src/libcamera/device_enumerator.cpp", + "src/libcamera/device_enumerator_sysfs.cpp", + "src/libcamera/dma_buf_allocator.cpp", + "src/libcamera/fence.cpp", + "src/libcamera/formats.cpp", + "src/libcamera/framebuffer.cpp", + "src/libcamera/framebuffer_allocator.cpp", + "src/libcamera/geometry.cpp", + "src/libcamera/global_configuration.cpp", + "src/libcamera/ipa_controls.cpp", + "src/libcamera/ipa_data_serializer.cpp", + "src/libcamera/ipa_interface.cpp", + "src/libcamera/ipa_manager.cpp", + "src/libcamera/ipa_module.cpp", + "src/libcamera/ipa_proxy.cpp", + "src/libcamera/ipc_pipe.cpp", + "src/libcamera/ipc_pipe_unixsocket.cpp", + "src/libcamera/ipc_unixsocket.cpp", + "src/libcamera/mapped_framebuffer.cpp", + "src/libcamera/matrix.cpp", + "src/libcamera/media_device.cpp", + "src/libcamera/media_object.cpp", + "src/libcamera/media_pipeline.cpp", + "src/libcamera/orientation.cpp", + "src/libcamera/pipeline/rpi/common/*.cpp", + "src/libcamera/pipeline/rpi/pisp/pisp.cpp", + "src/libcamera/pipeline/rpi/vc4/vc4.cpp", + "src/libcamera/pipeline_handler.cpp", + "src/libcamera/pixel_format.cpp", + "src/libcamera/process.cpp", + "src/libcamera/pub_key.cpp", + "src/libcamera/request.cpp", + "src/libcamera/sensor/*.cpp", + "src/libcamera/shared_mem_object.cpp", + "src/libcamera/source_paths.cpp", + "src/libcamera/stream.cpp", + "src/libcamera/sysfs.cpp", + "src/libcamera/transform.cpp", + "src/libcamera/v4l2_device.cpp", + "src/libcamera/v4l2_pixelformat.cpp", + "src/libcamera/v4l2_request.cpp", + "src/libcamera/v4l2_subdevice.cpp", + "src/libcamera/v4l2_videodevice.cpp", + "src/libcamera/value_node.cpp", + "src/libcamera/vector.cpp", + "src/libcamera/yaml_parser.cpp", + ], + cflags: [ + "-DLIBCAMERA_BASE_PRIVATE", + "-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST", + "-Wextra-semi", + "-Wnon-virtual-dtor", + "-Wthread-safety", + "-std=c++20", + ], + shared_libs: [ + "libcamera-base", + "libpisp", + ], + static_libs: ["libyaml"], + local_include_dirs: [ + "include", + "meson_generated/include", + "meson_generated/include/libcamera", + "meson_generated/include/libcamera/internal", + "meson_generated/include/libcamera/ipa", + "meson_generated/src/libcamera", + "meson_generated/src/libcamera/proxy", + "src/libcamera", + ], + soc_specific: true, + header_libs: ["libpisp_headers"], + defaults: ["libcamera-rpi-defaults"], +} + +cc_library_shared { + name: "libcamera-base", + srcs: ["src/libcamera/base/*.cpp"], + cflags: [ + "-DLIBCAMERA_BASE_PRIVATE", + "-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST", + "-Wextra-semi", + "-Wnon-virtual-dtor", + "-Wthread-safety", + "-pthread", + "-std=c++20", + ], + local_include_dirs: [ + "include", + "meson_generated/include", + "src/libcamera/base", + ], + soc_specific: true, + defaults: ["libcamera-rpi-defaults"], +} + +cc_library_shared { + name: "ipa_rpi_vc4", + srcs: ["src/ipa/rpi/vc4/vc4.cpp"], + cflags: [ + "-DLIBCAMERA_BASE_PRIVATE", + "-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST", + "-Wextra-semi", + "-Wnon-virtual-dtor", + "-Wthread-safety", + "-std=c++20", + ], + shared_libs: [ + "libcamera", + "libcamera-base", + ], + static_libs: ["libcamera-rpi_src_ipa_libipa_libipa_a"], + whole_static_libs: [ + "libcamera-rpi_src_ipa_rpi_cam_helper_librpi_ipa_cam_helper_a", + "libcamera-rpi_src_ipa_rpi_common_librpi_ipa_common_a", + "libcamera-rpi_src_ipa_rpi_controller_librpi_ipa_controller_a", + ], + local_include_dirs: [ + "include", + "meson_generated/include", + "meson_generated/include/libcamera", + "meson_generated/include/libcamera/ipa", + "src/ipa", + "src/ipa/rpi", + "src/ipa/rpi/vc4", + ], + soc_specific: true, + relative_install_path: "libcamera/ipa", + defaults: ["libcamera-rpi-defaults"], +} + +cc_library_static { + name: "libcamera-rpi_src_ipa_rpi_controller_librpi_ipa_controller_a", + srcs: [ + "src/ipa/rpi/controller/*.cpp", + "src/ipa/rpi/controller/rpi/af.cpp", + "src/ipa/rpi/controller/rpi/agc.cpp", + "src/ipa/rpi/controller/rpi/agc_channel.cpp", + "src/ipa/rpi/controller/rpi/alsc.cpp", + "src/ipa/rpi/controller/rpi/awb.cpp", + "src/ipa/rpi/controller/rpi/awb_bayes.cpp", + "src/ipa/rpi/controller/rpi/black_level.cpp", + "src/ipa/rpi/controller/rpi/cac.cpp", + "src/ipa/rpi/controller/rpi/ccm.cpp", + "src/ipa/rpi/controller/rpi/contrast.cpp", + "src/ipa/rpi/controller/rpi/decompand.cpp", + "src/ipa/rpi/controller/rpi/denoise.cpp", + "src/ipa/rpi/controller/rpi/dpc.cpp", + "src/ipa/rpi/controller/rpi/geq.cpp", + "src/ipa/rpi/controller/rpi/hdr.cpp", + "src/ipa/rpi/controller/rpi/lux.cpp", + "src/ipa/rpi/controller/rpi/noise.cpp", + "src/ipa/rpi/controller/rpi/saturation.cpp", + "src/ipa/rpi/controller/rpi/sdn.cpp", + "src/ipa/rpi/controller/rpi/sharpen.cpp", + "src/ipa/rpi/controller/rpi/tonemap.cpp", + ], + cflags: [ + "-DLIBCAMERA_BASE_PRIVATE", + "-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST", + "-Wextra-semi", + "-Wnon-virtual-dtor", + "-Wthread-safety", + "-std=c++20", + ], + local_include_dirs: [ + "include", + "meson_generated/include", + "meson_generated/include/libcamera", + "meson_generated/include/libcamera/ipa", + "src/ipa", + "src/ipa/rpi/controller", + ], + defaults: ["libcamera-rpi-defaults"], +} + +cc_library_static { + name: "libcamera-rpi_src_ipa_rpi_common_librpi_ipa_common_a", + srcs: ["src/ipa/rpi/common/ipa_base.cpp"], + cflags: [ + "-DLIBCAMERA_BASE_PRIVATE", + "-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST", + "-Wextra-semi", + "-Wnon-virtual-dtor", + "-Wthread-safety", + "-std=c++20", + ], + local_include_dirs: [ + "include", + "meson_generated/include", + "meson_generated/include/libcamera", + "meson_generated/include/libcamera/ipa", + "src/ipa/rpi", + "src/ipa/rpi/common", + ], + defaults: ["libcamera-rpi-defaults"], +} + +cc_library_static { + name: "libcamera-rpi_src_ipa_rpi_cam_helper_librpi_ipa_cam_helper_a", + srcs: [ + "src/ipa/rpi/cam_helper/*.cpp", + "src/ipa/rpi/cam_helper/imx500_tensor_parser/imx500_tensor_parser.cpp", + ], + cflags: [ + "-DLIBCAMERA_BASE_PRIVATE", + "-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST", + "-Wextra-semi", + "-Wnon-virtual-dtor", + "-Wthread-safety", + "-std=c++20", + ], + local_include_dirs: [ + "include", + "meson_generated/include", + "meson_generated/include/libcamera", + "meson_generated/include/libcamera/ipa", + "src/ipa/rpi", + "src/ipa/rpi/cam_helper", + ], + defaults: ["libcamera-rpi-defaults"], +} + +cc_library_static { + name: "libcamera-rpi_src_ipa_libipa_libipa_a", + srcs: ["src/ipa/libipa/*.cpp"], + cflags: [ + "-DLIBCAMERA_BASE_PRIVATE", + "-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST", + "-Wextra-semi", + "-Wnon-virtual-dtor", + "-Wthread-safety", + "-std=c++20", + ], + local_include_dirs: [ + "include", + "meson_generated/include", + "meson_generated/include/libcamera", + "meson_generated/include/libcamera/ipa", + "src/ipa/libipa", + ], + defaults: ["libcamera-rpi-defaults"], +} + +cc_library_shared { + name: "ipa_rpi_pisp", + srcs: ["src/ipa/rpi/pisp/pisp.cpp"], + cflags: [ + "-DLIBCAMERA_BASE_PRIVATE", + "-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST", + "-Wextra-semi", + "-Wno-address-of-packed-member", + "-Wnon-virtual-dtor", + "-Wthread-safety", + "-std=c++20", + ], + shared_libs: [ + "libcamera", + "libcamera-base", + "libpisp", + ], + static_libs: ["libcamera-rpi_src_ipa_libipa_libipa_a"], + whole_static_libs: [ + "libcamera-rpi_src_ipa_rpi_cam_helper_librpi_ipa_cam_helper_a", + "libcamera-rpi_src_ipa_rpi_common_librpi_ipa_common_a", + "libcamera-rpi_src_ipa_rpi_controller_librpi_ipa_controller_a", + ], + local_include_dirs: [ + "include", + "meson_generated/include", + "meson_generated/include/libcamera", + "meson_generated/include/libcamera/ipa", + "src/ipa", + "src/ipa/rpi", + "src/ipa/rpi/pisp", + ], + soc_specific: true, + relative_install_path: "libcamera/ipa", + header_libs: ["libpisp_headers"], + defaults: ["libcamera-rpi-defaults"], +} + +cc_library_shared { + name: "camera.libcamera", + srcs: [ + "src/android/*.cpp", + "src/android/jpeg/encoder_libjpeg.cpp", + "src/android/jpeg/exif.cpp", + "src/android/jpeg/post_processor_jpeg.cpp", + "src/android/jpeg/thumbnailer.cpp", + "src/android/mm/generic_camera_buffer.cpp", + "src/android/mm/generic_frame_buffer_allocator.cpp", + "src/android/mm/graphic_buffer_allocator_stub.cpp", + "src/android/yuv/post_processor_yuv.cpp", + ], + cflags: [ + "-DHAVE_LIBJPEG", + "-DLIBCAMERA_BASE_PRIVATE", + "-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST", + "-Wextra-semi", + "-Wnon-virtual-dtor", + "-Wthread-safety", + "-std=c++20", + ], + shared_libs: [ + "libcamera", + "libcamera-base", + "libexif", + "libjpeg", + "libyuv_chromium", + ], + static_libs: ["libcamera-rpi_src_android_libcamera_metadata_a"], + local_include_dirs: [ + "include", + "include/android/frameworks/native/libs/ui/include", + "include/android/hardware/libhardware/include", + "include/android/metadata", + "include/android/system/core/include", + "include/android/system/core/libutils/include", + "meson_generated/include", + "meson_generated/include/libcamera", + "meson_generated/include/libcamera/ipa", + "src/android", + ], + soc_specific: true, + relative_install_path: "hw", + defaults: ["libcamera-rpi-defaults"], +} + +cc_library_static { + name: "libcamera-rpi_src_android_libcamera_metadata_a", + srcs: ["src/android/metadata/camera_metadata.c"], + cflags: ["-Wno-shadow"], + local_include_dirs: [ + "include/android/frameworks/native/libs/ui/include", + "include/android/hardware/libhardware/include", + "include/android/metadata", + "include/android/system/core/include", + "include/android/system/core/libutils/include", + "src/android", + ], + defaults: ["libcamera-rpi-defaults"], +} + +cc_defaults { + name: "libcamera-rpi-defaults", + cflags: [ + "-D_FILE_OFFSET_BITS=64", + "-D_FORTIFY_SOURCE=2", + "-O3", + "-Wall", + "-Wextra", + "-Winvalid-pch", + "-Wmissing-declarations", + "-Wno-c99-designator", + "-Wno-macro-redefined", + "-Wshadow", + "-fPIC", + "-fdiagnostics-color=always", + ], + defaults: ["libcamera-rpi-raw-defaults"], +} + +cc_defaults { + name: "libcamera-rpi-raw-defaults", + cflags: ["-include meson_generated/config.h"], + rtti: true, +} diff --git a/meson_generated/config.h b/meson_generated/config.h new file mode 100644 index 00000000..21f746e6 --- /dev/null +++ b/meson_generated/config.h @@ -0,0 +1,31 @@ +/* + * Autogenerated by the Meson build system. + * Do not edit, your changes will be lost. + */ + +#pragma once + +#define HAVE_BACKTRACE 1 + +#define HAVE_CLOSE_RANGE 1 + +#define HAVE_FILE_SEALS 1 + +#define HAVE_IPA_PUBKEY 1 + +#define HAVE_LOCALE_T 1 + +#define HAVE_MEMFD_CREATE 1 + +#define HAVE_POSIX_IOCTL 1 + +#define IPA_CONFIG_DIR "/vendor/etc/libcamera/ipa:/usr/local/share/libcamera/ipa" + +#define IPA_MODULE_DIR "/usr/local/lib/libcamera/ipa" + +#define IPA_PROXY_DIR "/usr/local/libexec/libcamera" + +#define LIBCAMERA_DATA_DIR "/usr/local/share/libcamera" + +#define LIBCAMERA_SYSCONF_DIR "/vendor/etc/libcamera" + diff --git a/meson_generated/include/libcamera/control_ids.h b/meson_generated/include/libcamera/control_ids.h new file mode 100644 index 00000000..b700ffcb --- /dev/null +++ b/meson_generated/include/libcamera/control_ids.h @@ -0,0 +1,513 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * Controls ID list + * + * This file is auto-generated. Do not edit. + */ + +#pragma once + +#include +#include +#include +#include +#include + +#include + +namespace libcamera { + +namespace controls { + +extern const ControlIdMap controls; + + +enum { + AE_ENABLE = 1, + AE_STATE = 2, + AE_METERING_MODE = 3, + AE_CONSTRAINT_MODE = 4, + AE_EXPOSURE_MODE = 5, + EXPOSURE_VALUE = 6, + EXPOSURE_TIME = 7, + EXPOSURE_TIME_MODE = 8, + ANALOGUE_GAIN = 9, + ANALOGUE_GAIN_MODE = 10, + AE_FLICKER_MODE = 11, + AE_FLICKER_PERIOD = 12, + AE_FLICKER_DETECTED = 13, + BRIGHTNESS = 14, + CONTRAST = 15, + LUX = 16, + AWB_ENABLE = 17, + AWB_MODE = 18, + AWB_LOCKED = 19, + COLOUR_GAINS = 20, + COLOUR_TEMPERATURE = 21, + SATURATION = 22, + SENSOR_BLACK_LEVELS = 23, + SHARPNESS = 24, + FOCUS_FO_M = 25, + COLOUR_CORRECTION_MATRIX = 26, + SCALER_CROP = 27, + DIGITAL_GAIN = 28, + FRAME_DURATION = 29, + FRAME_DURATION_LIMITS = 30, + SENSOR_TEMPERATURE = 31, + SENSOR_TIMESTAMP = 32, + AF_MODE = 33, + AF_RANGE = 34, + AF_SPEED = 35, + AF_METERING = 36, + AF_WINDOWS = 37, + AF_TRIGGER = 38, + AF_PAUSE = 39, + LENS_POSITION = 40, + AF_STATE = 41, + AF_PAUSE_STATE = 42, + HDR_MODE = 43, + HDR_CHANNEL = 44, + GAMMA = 45, + DEBUG_METADATA_ENABLE = 46, + FRAME_WALL_CLOCK = 47, + WDR_MODE = 48, + WDR_STRENGTH = 49, + WDR_MAX_BRIGHT_PIXELS = 50, + LENS_DEWARP_ENABLE = 51, + LENS_SHADING_CORRECTION_ENABLE = 52, + HUE = 53, +}; + + +extern const Control AeEnable; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_AE_ENABLE +enum AeStateEnum { + AeStateIdle = 0, + AeStateSearching = 1, + AeStateConverged = 2, +}; +extern const std::array AeStateValues; +extern const std::map AeStateNameValueMap; +extern const Control AeState; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_AE_STATE +enum AeMeteringModeEnum { + MeteringCentreWeighted = 0, + MeteringSpot = 1, + MeteringMatrix = 2, + MeteringCustom = 3, +}; +extern const std::array AeMeteringModeValues; +extern const std::map AeMeteringModeNameValueMap; +extern const Control AeMeteringMode; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_AE_METERING_MODE +enum AeConstraintModeEnum { + ConstraintNormal = 0, + ConstraintHighlight = 1, + ConstraintShadows = 2, + ConstraintCustom = 3, +}; +extern const std::array AeConstraintModeValues; +extern const std::map AeConstraintModeNameValueMap; +extern const Control AeConstraintMode; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_AE_CONSTRAINT_MODE +enum AeExposureModeEnum { + ExposureNormal = 0, + ExposureShort = 1, + ExposureLong = 2, + ExposureCustom = 3, +}; +extern const std::array AeExposureModeValues; +extern const std::map AeExposureModeNameValueMap; +extern const Control AeExposureMode; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_AE_EXPOSURE_MODE +extern const Control ExposureValue; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_EXPOSURE_VALUE +extern const Control ExposureTime; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_EXPOSURE_TIME +enum ExposureTimeModeEnum { + ExposureTimeModeAuto = 0, + ExposureTimeModeManual = 1, +}; +extern const std::array ExposureTimeModeValues; +extern const std::map ExposureTimeModeNameValueMap; +extern const Control ExposureTimeMode; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_EXPOSURE_TIME_MODE +extern const Control AnalogueGain; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_ANALOGUE_GAIN +enum AnalogueGainModeEnum { + AnalogueGainModeAuto = 0, + AnalogueGainModeManual = 1, +}; +extern const std::array AnalogueGainModeValues; +extern const std::map AnalogueGainModeNameValueMap; +extern const Control AnalogueGainMode; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_ANALOGUE_GAIN_MODE +enum AeFlickerModeEnum { + FlickerOff = 0, + FlickerManual = 1, + FlickerAuto = 2, +}; +extern const std::array AeFlickerModeValues; +extern const std::map AeFlickerModeNameValueMap; +extern const Control AeFlickerMode; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_AE_FLICKER_MODE +extern const Control AeFlickerPeriod; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_AE_FLICKER_PERIOD +extern const Control AeFlickerDetected; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_AE_FLICKER_DETECTED +extern const Control Brightness; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_BRIGHTNESS +extern const Control Contrast; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_CONTRAST +extern const Control Lux; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_LUX +extern const Control AwbEnable; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_AWB_ENABLE +enum AwbModeEnum { + AwbAuto = 0, + AwbIncandescent = 1, + AwbTungsten = 2, + AwbFluorescent = 3, + AwbIndoor = 4, + AwbDaylight = 5, + AwbCloudy = 6, + AwbCustom = 7, +}; +extern const std::array AwbModeValues; +extern const std::map AwbModeNameValueMap; +extern const Control AwbMode; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_AWB_MODE +extern const Control AwbLocked; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_AWB_LOCKED +extern const Control> ColourGains; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_COLOUR_GAINS +extern const Control ColourTemperature; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_COLOUR_TEMPERATURE +extern const Control Saturation; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_SATURATION +extern const Control> SensorBlackLevels; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_SENSOR_BLACK_LEVELS +extern const Control Sharpness; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_SHARPNESS +extern const Control FocusFoM; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_FOCUS_FO_M +extern const Control> ColourCorrectionMatrix; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_COLOUR_CORRECTION_MATRIX +extern const Control ScalerCrop; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_SCALER_CROP +extern const Control DigitalGain; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_DIGITAL_GAIN +extern const Control FrameDuration; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_FRAME_DURATION +extern const Control> FrameDurationLimits; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_FRAME_DURATION_LIMITS +extern const Control SensorTemperature; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_SENSOR_TEMPERATURE +extern const Control SensorTimestamp; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_SENSOR_TIMESTAMP +enum AfModeEnum { + AfModeManual = 0, + AfModeAuto = 1, + AfModeContinuous = 2, +}; +extern const std::array AfModeValues; +extern const std::map AfModeNameValueMap; +extern const Control AfMode; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_AF_MODE +enum AfRangeEnum { + AfRangeNormal = 0, + AfRangeMacro = 1, + AfRangeFull = 2, +}; +extern const std::array AfRangeValues; +extern const std::map AfRangeNameValueMap; +extern const Control AfRange; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_AF_RANGE +enum AfSpeedEnum { + AfSpeedNormal = 0, + AfSpeedFast = 1, +}; +extern const std::array AfSpeedValues; +extern const std::map AfSpeedNameValueMap; +extern const Control AfSpeed; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_AF_SPEED +enum AfMeteringEnum { + AfMeteringAuto = 0, + AfMeteringWindows = 1, +}; +extern const std::array AfMeteringValues; +extern const std::map AfMeteringNameValueMap; +extern const Control AfMetering; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_AF_METERING +extern const Control> AfWindows; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_AF_WINDOWS +enum AfTriggerEnum { + AfTriggerStart = 0, + AfTriggerCancel = 1, +}; +extern const std::array AfTriggerValues; +extern const std::map AfTriggerNameValueMap; +extern const Control AfTrigger; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_AF_TRIGGER +enum AfPauseEnum { + AfPauseImmediate = 0, + AfPauseDeferred = 1, + AfPauseResume = 2, +}; +extern const std::array AfPauseValues; +extern const std::map AfPauseNameValueMap; +extern const Control AfPause; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_AF_PAUSE +extern const Control LensPosition; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_LENS_POSITION +enum AfStateEnum { + AfStateIdle = 0, + AfStateScanning = 1, + AfStateFocused = 2, + AfStateFailed = 3, +}; +extern const std::array AfStateValues; +extern const std::map AfStateNameValueMap; +extern const Control AfState; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_AF_STATE +enum AfPauseStateEnum { + AfPauseStateRunning = 0, + AfPauseStatePausing = 1, + AfPauseStatePaused = 2, +}; +extern const std::array AfPauseStateValues; +extern const std::map AfPauseStateNameValueMap; +extern const Control AfPauseState; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_AF_PAUSE_STATE +enum HdrModeEnum { + HdrModeOff = 0, + HdrModeMultiExposureUnmerged = 1, + HdrModeMultiExposure = 2, + HdrModeSingleExposure = 3, + HdrModeNight = 4, +}; +extern const std::array HdrModeValues; +extern const std::map HdrModeNameValueMap; +extern const Control HdrMode; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_HDR_MODE +enum HdrChannelEnum { + HdrChannelNone = 0, + HdrChannelShort = 1, + HdrChannelMedium = 2, + HdrChannelLong = 3, +}; +extern const std::array HdrChannelValues; +extern const std::map HdrChannelNameValueMap; +extern const Control HdrChannel; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_HDR_CHANNEL +extern const Control Gamma; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_GAMMA +extern const Control DebugMetadataEnable; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_DEBUG_METADATA_ENABLE +extern const Control FrameWallClock; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_FRAME_WALL_CLOCK +enum WdrModeEnum { + WdrOff = 0, + WdrLinear = 1, + WdrPower = 2, + WdrExponential = 3, + WdrHistogramEqualization = 4, +}; +extern const std::array WdrModeValues; +extern const std::map WdrModeNameValueMap; +extern const Control WdrMode; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_WDR_MODE +extern const Control WdrStrength; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_WDR_STRENGTH +extern const Control WdrMaxBrightPixels; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_WDR_MAX_BRIGHT_PIXELS +extern const Control LensDewarpEnable; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_LENS_DEWARP_ENABLE +extern const Control LensShadingCorrectionEnable; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_LENS_SHADING_CORRECTION_ENABLE +extern const Control Hue; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_CONTROLS_HUE + +namespace draft { + +#define LIBCAMERA_HAS_DRAFT_VENDOR_CONTROLS + + +enum { + AE_PRECAPTURE_TRIGGER = 10001, + NOISE_REDUCTION_MODE = 10002, + COLOR_CORRECTION_ABERRATION_MODE = 10003, + AWB_STATE = 10004, + SENSOR_ROLLING_SHUTTER_SKEW = 10005, + LENS_SHADING_MAP_MODE = 10006, + PIPELINE_DEPTH = 10007, + MAX_LATENCY = 10008, + TEST_PATTERN_MODE = 10009, + FACE_DETECT_MODE = 10010, + FACE_DETECT_FACE_RECTANGLES = 10011, + FACE_DETECT_FACE_SCORES = 10012, + FACE_DETECT_FACE_LANDMARKS = 10013, + FACE_DETECT_FACE_IDS = 10014, +}; + + +enum AePrecaptureTriggerEnum { + AePrecaptureTriggerIdle = 0, + AePrecaptureTriggerStart = 1, + AePrecaptureTriggerCancel = 2, +}; +extern const std::array AePrecaptureTriggerValues; +extern const std::map AePrecaptureTriggerNameValueMap; +extern const Control AePrecaptureTrigger; +#define LIBCAMERA_HAS_DRAFT_VENDOR_CONTROLS_AE_PRECAPTURE_TRIGGER +enum NoiseReductionModeEnum { + NoiseReductionModeOff = 0, + NoiseReductionModeFast = 1, + NoiseReductionModeHighQuality = 2, + NoiseReductionModeMinimal = 3, + NoiseReductionModeZSL = 4, +}; +extern const std::array NoiseReductionModeValues; +extern const std::map NoiseReductionModeNameValueMap; +extern const Control NoiseReductionMode; +#define LIBCAMERA_HAS_DRAFT_VENDOR_CONTROLS_NOISE_REDUCTION_MODE +enum ColorCorrectionAberrationModeEnum { + ColorCorrectionAberrationOff = 0, + ColorCorrectionAberrationFast = 1, + ColorCorrectionAberrationHighQuality = 2, +}; +extern const std::array ColorCorrectionAberrationModeValues; +extern const std::map ColorCorrectionAberrationModeNameValueMap; +extern const Control ColorCorrectionAberrationMode; +#define LIBCAMERA_HAS_DRAFT_VENDOR_CONTROLS_COLOR_CORRECTION_ABERRATION_MODE +enum AwbStateEnum { + AwbStateInactive = 0, + AwbStateSearching = 1, + AwbConverged = 2, + AwbLocked = 3, +}; +extern const std::array AwbStateValues; +extern const std::map AwbStateNameValueMap; +extern const Control AwbState; +#define LIBCAMERA_HAS_DRAFT_VENDOR_CONTROLS_AWB_STATE +extern const Control SensorRollingShutterSkew; +#define LIBCAMERA_HAS_DRAFT_VENDOR_CONTROLS_SENSOR_ROLLING_SHUTTER_SKEW +enum LensShadingMapModeEnum { + LensShadingMapModeOff = 0, + LensShadingMapModeOn = 1, +}; +extern const std::array LensShadingMapModeValues; +extern const std::map LensShadingMapModeNameValueMap; +extern const Control LensShadingMapMode; +#define LIBCAMERA_HAS_DRAFT_VENDOR_CONTROLS_LENS_SHADING_MAP_MODE +extern const Control PipelineDepth; +#define LIBCAMERA_HAS_DRAFT_VENDOR_CONTROLS_PIPELINE_DEPTH +extern const Control MaxLatency; +#define LIBCAMERA_HAS_DRAFT_VENDOR_CONTROLS_MAX_LATENCY +enum TestPatternModeEnum { + TestPatternModeOff = 0, + TestPatternModeSolidColor = 1, + TestPatternModeColorBars = 2, + TestPatternModeColorBarsFadeToGray = 3, + TestPatternModePn9 = 4, + TestPatternModeCustom1 = 256, +}; +extern const std::array TestPatternModeValues; +extern const std::map TestPatternModeNameValueMap; +extern const Control TestPatternMode; +#define LIBCAMERA_HAS_DRAFT_VENDOR_CONTROLS_TEST_PATTERN_MODE +enum FaceDetectModeEnum { + FaceDetectModeOff = 0, + FaceDetectModeSimple = 1, + FaceDetectModeFull = 2, +}; +extern const std::array FaceDetectModeValues; +extern const std::map FaceDetectModeNameValueMap; +extern const Control FaceDetectMode; +#define LIBCAMERA_HAS_DRAFT_VENDOR_CONTROLS_FACE_DETECT_MODE +extern const Control> FaceDetectFaceRectangles; +#define LIBCAMERA_HAS_DRAFT_VENDOR_CONTROLS_FACE_DETECT_FACE_RECTANGLES +extern const Control> FaceDetectFaceScores; +#define LIBCAMERA_HAS_DRAFT_VENDOR_CONTROLS_FACE_DETECT_FACE_SCORES +extern const Control> FaceDetectFaceLandmarks; +#define LIBCAMERA_HAS_DRAFT_VENDOR_CONTROLS_FACE_DETECT_FACE_LANDMARKS +extern const Control> FaceDetectFaceIds; +#define LIBCAMERA_HAS_DRAFT_VENDOR_CONTROLS_FACE_DETECT_FACE_IDS + +} /* namespace draft */ + +namespace rpi { + +#define LIBCAMERA_HAS_RPI_VENDOR_CONTROLS + + +enum { + STATS_OUTPUT_ENABLE = 20001, + BCM2835_STATS_OUTPUT = 20002, + SCALER_CROPS = 20003, + PISP_STATS_OUTPUT = 20004, + SYNC_MODE = 20005, + SYNC_READY = 20006, + SYNC_TIMER = 20007, + SYNC_FRAMES = 20008, + CNN_OUTPUT_TENSOR = 20009, + CNN_OUTPUT_TENSOR_INFO = 20010, + CNN_ENABLE_INPUT_TENSOR = 20011, + CNN_INPUT_TENSOR = 20012, + CNN_INPUT_TENSOR_INFO = 20013, + CNN_KPI_INFO = 20014, +}; + + +extern const Control StatsOutputEnable; +#define LIBCAMERA_HAS_RPI_VENDOR_CONTROLS_STATS_OUTPUT_ENABLE +extern const Control> Bcm2835StatsOutput; +#define LIBCAMERA_HAS_RPI_VENDOR_CONTROLS_BCM2835_STATS_OUTPUT +extern const Control> ScalerCrops; +#define LIBCAMERA_HAS_RPI_VENDOR_CONTROLS_SCALER_CROPS +extern const Control> PispStatsOutput; +#define LIBCAMERA_HAS_RPI_VENDOR_CONTROLS_PISP_STATS_OUTPUT +enum SyncModeEnum { + SyncModeOff = 0, + SyncModeServer = 1, + SyncModeClient = 2, +}; +extern const std::array SyncModeValues; +extern const std::map SyncModeNameValueMap; +extern const Control SyncMode; +#define LIBCAMERA_HAS_RPI_VENDOR_CONTROLS_SYNC_MODE +extern const Control SyncReady; +#define LIBCAMERA_HAS_RPI_VENDOR_CONTROLS_SYNC_READY +extern const Control SyncTimer; +#define LIBCAMERA_HAS_RPI_VENDOR_CONTROLS_SYNC_TIMER +extern const Control SyncFrames; +#define LIBCAMERA_HAS_RPI_VENDOR_CONTROLS_SYNC_FRAMES +extern const Control> CnnOutputTensor; +#define LIBCAMERA_HAS_RPI_VENDOR_CONTROLS_CNN_OUTPUT_TENSOR +extern const Control> CnnOutputTensorInfo; +#define LIBCAMERA_HAS_RPI_VENDOR_CONTROLS_CNN_OUTPUT_TENSOR_INFO +extern const Control CnnEnableInputTensor; +#define LIBCAMERA_HAS_RPI_VENDOR_CONTROLS_CNN_ENABLE_INPUT_TENSOR +extern const Control> CnnInputTensor; +#define LIBCAMERA_HAS_RPI_VENDOR_CONTROLS_CNN_INPUT_TENSOR +extern const Control> CnnInputTensorInfo; +#define LIBCAMERA_HAS_RPI_VENDOR_CONTROLS_CNN_INPUT_TENSOR_INFO +extern const Control> CnnKpiInfo; +#define LIBCAMERA_HAS_RPI_VENDOR_CONTROLS_CNN_KPI_INFO + +} /* namespace rpi */ + +namespace debug { + +#define LIBCAMERA_HAS_DEBUG_VENDOR_CONTROLS + + + + +} /* namespace debug */ + +} /* namespace controls */ + +} /* namespace libcamera */ \ No newline at end of file diff --git a/meson_generated/include/libcamera/formats.h b/meson_generated/include/libcamera/formats.h new file mode 100644 index 00000000..73b3dfb5 --- /dev/null +++ b/meson_generated/include/libcamera/formats.h @@ -0,0 +1,124 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Google Inc. + * + * Formats + * + * This file is auto-generated. Do not edit. + */ + +#pragma once + +#include + +#include + +namespace libcamera { + +namespace formats { + +namespace { + +constexpr uint32_t __fourcc(char a, char b, char c, char d) +{ + return (static_cast(a) << 0) | + (static_cast(b) << 8) | + (static_cast(c) << 16) | + (static_cast(d) << 24); +} + +constexpr uint64_t __mod(unsigned int vendor, unsigned int mod) +{ + return (static_cast(vendor) << 56) | + (static_cast(mod) << 0); +} + +constexpr uint32_t kDrmFormatBigEndian = uint32_t(1) << 31; /* DRM_FORMAT_BIG_ENDIAN */ + +} /* namespace */ + +constexpr PixelFormat R8(__fourcc('R', '8', ' ', ' '), __mod(0, 0)); +constexpr PixelFormat R10(__fourcc('R', '1', '0', ' '), __mod(0, 0)); +constexpr PixelFormat R12(__fourcc('R', '1', '2', ' '), __mod(0, 0)); +constexpr PixelFormat R16(__fourcc('R', '1', '6', ' '), __mod(0, 0)); +constexpr PixelFormat RGB565(__fourcc('R', 'G', '1', '6'), __mod(0, 0)); +constexpr PixelFormat RGB565_BE(__fourcc('R', 'G', '1', '6') | kDrmFormatBigEndian, __mod(0, 0)); +constexpr PixelFormat RGB888(__fourcc('R', 'G', '2', '4'), __mod(0, 0)); +constexpr PixelFormat BGR888(__fourcc('B', 'G', '2', '4'), __mod(0, 0)); +constexpr PixelFormat XRGB8888(__fourcc('X', 'R', '2', '4'), __mod(0, 0)); +constexpr PixelFormat XBGR8888(__fourcc('X', 'B', '2', '4'), __mod(0, 0)); +constexpr PixelFormat RGBX8888(__fourcc('R', 'X', '2', '4'), __mod(0, 0)); +constexpr PixelFormat BGRX8888(__fourcc('B', 'X', '2', '4'), __mod(0, 0)); +constexpr PixelFormat ARGB8888(__fourcc('A', 'R', '2', '4'), __mod(0, 0)); +constexpr PixelFormat ABGR8888(__fourcc('A', 'B', '2', '4'), __mod(0, 0)); +constexpr PixelFormat RGBA8888(__fourcc('R', 'A', '2', '4'), __mod(0, 0)); +constexpr PixelFormat BGRA8888(__fourcc('B', 'A', '2', '4'), __mod(0, 0)); +constexpr PixelFormat RGB161616(__fourcc('R', 'G', '4', '8'), __mod(0, 0)); +constexpr PixelFormat BGR161616(__fourcc('B', 'G', '4', '8'), __mod(0, 0)); +constexpr PixelFormat YUYV(__fourcc('Y', 'U', 'Y', 'V'), __mod(0, 0)); +constexpr PixelFormat YVYU(__fourcc('Y', 'V', 'Y', 'U'), __mod(0, 0)); +constexpr PixelFormat UYVY(__fourcc('U', 'Y', 'V', 'Y'), __mod(0, 0)); +constexpr PixelFormat VYUY(__fourcc('V', 'Y', 'U', 'Y'), __mod(0, 0)); +constexpr PixelFormat AVUY8888(__fourcc('A', 'V', 'U', 'Y'), __mod(0, 0)); +constexpr PixelFormat XVUY8888(__fourcc('X', 'V', 'U', 'Y'), __mod(0, 0)); +constexpr PixelFormat NV12(__fourcc('N', 'V', '1', '2'), __mod(0, 0)); +constexpr PixelFormat NV21(__fourcc('N', 'V', '2', '1'), __mod(0, 0)); +constexpr PixelFormat NV16(__fourcc('N', 'V', '1', '6'), __mod(0, 0)); +constexpr PixelFormat NV61(__fourcc('N', 'V', '6', '1'), __mod(0, 0)); +constexpr PixelFormat NV24(__fourcc('N', 'V', '2', '4'), __mod(0, 0)); +constexpr PixelFormat NV42(__fourcc('N', 'V', '4', '2'), __mod(0, 0)); +constexpr PixelFormat YUV420(__fourcc('Y', 'U', '1', '2'), __mod(0, 0)); +constexpr PixelFormat YVU420(__fourcc('Y', 'V', '1', '2'), __mod(0, 0)); +constexpr PixelFormat YUV422(__fourcc('Y', 'U', '1', '6'), __mod(0, 0)); +constexpr PixelFormat YVU422(__fourcc('Y', 'V', '1', '6'), __mod(0, 0)); +constexpr PixelFormat YUV444(__fourcc('Y', 'U', '2', '4'), __mod(0, 0)); +constexpr PixelFormat YVU444(__fourcc('Y', 'V', '2', '4'), __mod(0, 0)); +constexpr PixelFormat MJPEG(__fourcc('M', 'J', 'P', 'G'), __mod(0, 0)); +constexpr PixelFormat SRGGB8(__fourcc('R', 'G', 'G', 'B'), __mod(0, 0)); +constexpr PixelFormat SGRBG8(__fourcc('G', 'R', 'B', 'G'), __mod(0, 0)); +constexpr PixelFormat SGBRG8(__fourcc('G', 'B', 'R', 'G'), __mod(0, 0)); +constexpr PixelFormat SBGGR8(__fourcc('B', 'A', '8', '1'), __mod(0, 0)); +constexpr PixelFormat SRGGB10(__fourcc('R', 'G', '1', '0'), __mod(0, 0)); +constexpr PixelFormat SGRBG10(__fourcc('B', 'A', '1', '0'), __mod(0, 0)); +constexpr PixelFormat SGBRG10(__fourcc('G', 'B', '1', '0'), __mod(0, 0)); +constexpr PixelFormat SBGGR10(__fourcc('B', 'G', '1', '0'), __mod(0, 0)); +constexpr PixelFormat SRGGB12(__fourcc('R', 'G', '1', '2'), __mod(0, 0)); +constexpr PixelFormat SGRBG12(__fourcc('B', 'A', '1', '2'), __mod(0, 0)); +constexpr PixelFormat SGBRG12(__fourcc('G', 'B', '1', '2'), __mod(0, 0)); +constexpr PixelFormat SBGGR12(__fourcc('B', 'G', '1', '2'), __mod(0, 0)); +constexpr PixelFormat SRGGB14(__fourcc('R', 'G', '1', '4'), __mod(0, 0)); +constexpr PixelFormat SGRBG14(__fourcc('B', 'A', '1', '4'), __mod(0, 0)); +constexpr PixelFormat SGBRG14(__fourcc('G', 'B', '1', '4'), __mod(0, 0)); +constexpr PixelFormat SBGGR14(__fourcc('B', 'G', '1', '4'), __mod(0, 0)); +constexpr PixelFormat SRGGB16(__fourcc('R', 'G', 'B', '6'), __mod(0, 0)); +constexpr PixelFormat SGRBG16(__fourcc('G', 'R', '1', '6'), __mod(0, 0)); +constexpr PixelFormat SGBRG16(__fourcc('G', 'B', '1', '6'), __mod(0, 0)); +constexpr PixelFormat SBGGR16(__fourcc('B', 'Y', 'R', '2'), __mod(0, 0)); +constexpr PixelFormat R10_CSI2P(__fourcc('R', '1', '0', ' '), __mod(11, 1)); +constexpr PixelFormat R12_CSI2P(__fourcc('R', '1', '2', ' '), __mod(11, 1)); +constexpr PixelFormat SRGGB10_CSI2P(__fourcc('R', 'G', '1', '0'), __mod(11, 1)); +constexpr PixelFormat SGRBG10_CSI2P(__fourcc('B', 'A', '1', '0'), __mod(11, 1)); +constexpr PixelFormat SGBRG10_CSI2P(__fourcc('G', 'B', '1', '0'), __mod(11, 1)); +constexpr PixelFormat SBGGR10_CSI2P(__fourcc('B', 'G', '1', '0'), __mod(11, 1)); +constexpr PixelFormat SRGGB12_CSI2P(__fourcc('R', 'G', '1', '2'), __mod(11, 1)); +constexpr PixelFormat SGRBG12_CSI2P(__fourcc('B', 'A', '1', '2'), __mod(11, 1)); +constexpr PixelFormat SGBRG12_CSI2P(__fourcc('G', 'B', '1', '2'), __mod(11, 1)); +constexpr PixelFormat SBGGR12_CSI2P(__fourcc('B', 'G', '1', '2'), __mod(11, 1)); +constexpr PixelFormat SRGGB14_CSI2P(__fourcc('R', 'G', '1', '4'), __mod(11, 1)); +constexpr PixelFormat SGRBG14_CSI2P(__fourcc('B', 'A', '1', '4'), __mod(11, 1)); +constexpr PixelFormat SGBRG14_CSI2P(__fourcc('G', 'B', '1', '4'), __mod(11, 1)); +constexpr PixelFormat SBGGR14_CSI2P(__fourcc('B', 'G', '1', '4'), __mod(11, 1)); +constexpr PixelFormat SRGGB10_IPU3(__fourcc('R', 'G', '1', '0'), __mod(1, 13)); +constexpr PixelFormat SGRBG10_IPU3(__fourcc('B', 'A', '1', '0'), __mod(1, 13)); +constexpr PixelFormat SGBRG10_IPU3(__fourcc('G', 'B', '1', '0'), __mod(1, 13)); +constexpr PixelFormat SBGGR10_IPU3(__fourcc('B', 'G', '1', '0'), __mod(1, 13)); +constexpr PixelFormat RGGB_PISP_COMP1(__fourcc('R', 'G', 'B', '6'), __mod(12, 1)); +constexpr PixelFormat GRBG_PISP_COMP1(__fourcc('G', 'R', '1', '6'), __mod(12, 1)); +constexpr PixelFormat GBRG_PISP_COMP1(__fourcc('G', 'B', '1', '6'), __mod(12, 1)); +constexpr PixelFormat BGGR_PISP_COMP1(__fourcc('B', 'Y', 'R', '2'), __mod(12, 1)); +constexpr PixelFormat MONO_PISP_COMP1(__fourcc('R', '1', '6', ' '), __mod(12, 1)); + + +} /* namespace formats */ + +} /* namespace libcamera */ \ No newline at end of file diff --git a/meson_generated/include/libcamera/internal/tracepoints.h b/meson_generated/include/libcamera/internal/tracepoints.h new file mode 100644 index 00000000..4520088d --- /dev/null +++ b/meson_generated/include/libcamera/internal/tracepoints.h @@ -0,0 +1,237 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Google Inc. + * + * Tracepoints with lttng + * + * This file is auto-generated. Do not edit. + */ +#ifndef __LIBCAMERA_INTERNAL_TRACEPOINTS_H__ +#define __LIBCAMERA_INTERNAL_TRACEPOINTS_H__ + +#if HAVE_TRACING +#define LIBCAMERA_TRACEPOINT(...) tracepoint(libcamera, __VA_ARGS__) + +#define LIBCAMERA_TRACEPOINT_IPA_BEGIN(pipe, func) \ +tracepoint(libcamera, ipa_call_begin, #pipe, #func) + +#define LIBCAMERA_TRACEPOINT_IPA_END(pipe, func) \ +tracepoint(libcamera, ipa_call_end, #pipe, #func) + +#else + +namespace { + +template +inline void unused([[maybe_unused]] Args&& ...args) +{ +} + +} /* namespace */ + +#define LIBCAMERA_TRACEPOINT(category, ...) unused(__VA_ARGS__) + +#define LIBCAMERA_TRACEPOINT_IPA_BEGIN(pipe, func) +#define LIBCAMERA_TRACEPOINT_IPA_END(pipe, func) + +#endif /* HAVE_TRACING */ + +#endif /* __LIBCAMERA_INTERNAL_TRACEPOINTS_H__ */ + + +#if HAVE_TRACING + +#undef TRACEPOINT_PROVIDER +#define TRACEPOINT_PROVIDER libcamera + +#undef TRACEPOINT_INCLUDE +#define TRACEPOINT_INCLUDE "libcamera/internal/tracepoints.h" + +#if !defined(INCLUDE_LIBCAMERA_INTERNAL_TRACEPOINTS_TP_H) || defined(TRACEPOINT_HEADER_MULTI_READ) +#define INCLUDE_LIBCAMERA_INTERNAL_TRACEPOINTS_TP_H + +#include + +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Google Inc. + * + * buffer_enums.tp - Tracepoint definition for enums in the buffer class + */ + +TRACEPOINT_ENUM( + libcamera, + buffer_status, + TP_ENUM_VALUES( + ctf_enum_value("FrameSuccess", 0) + ctf_enum_value("FrameError", 1) + ctf_enum_value("FrameCancelled", 2) + ) +) + + +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Google Inc. + * + * request_enums.tp - Tracepoint definition for enums in the request class + */ + +TRACEPOINT_ENUM( + libcamera, + request_status, + TP_ENUM_VALUES( + ctf_enum_value("RequestPending", 0) + ctf_enum_value("RequestComplete", 1) + ctf_enum_value("RequestCancelled", 2) + ) +) + + +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Google Inc. + * + * pipeline.tp - Tracepoints for pipelines + */ + +TRACEPOINT_EVENT( + libcamera, + ipa_call_begin, + TP_ARGS( + const char *, pipe, + const char *, func + ), + TP_FIELDS( + ctf_string(pipeline_name, pipe) + ctf_string(function_name, func) + ) +) + +TRACEPOINT_EVENT( + libcamera, + ipa_call_end, + TP_ARGS( + const char *, pipe, + const char *, func + ), + TP_FIELDS( + ctf_string(pipeline_name, pipe) + ctf_string(function_name, func) + ) +) + + +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Google Inc. + * + * request.tp - Tracepoints for the request object + */ + +#include + +#include + +#include "libcamera/internal/request.h" + +TRACEPOINT_EVENT_CLASS( + libcamera, + request, + TP_ARGS( + libcamera::Request *, req + ), + TP_FIELDS( + ctf_integer_hex(uintptr_t, request, reinterpret_cast(req)) + ctf_integer(uint64_t, cookie, req->cookie()) + ctf_enum(libcamera, request_status, uint32_t, status, req->status()) + ) +) + +TRACEPOINT_EVENT_INSTANCE( + libcamera, + request, + request_construct, + TP_ARGS( + libcamera::Request *, req + ) +) + +TRACEPOINT_EVENT_INSTANCE( + libcamera, + request, + request_destroy, + TP_ARGS( + libcamera::Request *, req + ) +) + +TRACEPOINT_EVENT_INSTANCE( + libcamera, + request, + request_reuse, + TP_ARGS( + libcamera::Request *, req + ) +) + +TRACEPOINT_EVENT_INSTANCE( + libcamera, + request, + request_queue, + TP_ARGS( + libcamera::Request *, req + ) +) + +TRACEPOINT_EVENT_INSTANCE( + libcamera, + request, + request_device_queue, + TP_ARGS( + libcamera::Request *, req + ) +) + +TRACEPOINT_EVENT_INSTANCE( + libcamera, + request, + request_complete, + TP_ARGS( + libcamera::Request::Private *, req + ) +) + +TRACEPOINT_EVENT_INSTANCE( + libcamera, + request, + request_cancel, + TP_ARGS( + libcamera::Request::Private *, req + ) +) + +TRACEPOINT_EVENT( + libcamera, + request_complete_buffer, + TP_ARGS( + libcamera::Request::Private *, req, + libcamera::FrameBuffer *, buf + ), + TP_FIELDS( + ctf_integer_hex(uintptr_t, request, reinterpret_cast(req)) + ctf_integer(uint64_t, cookie, req->_o()->cookie()) + ctf_integer(int, status, req->_o()->status()) + ctf_integer_hex(uintptr_t, buffer, reinterpret_cast(buf)) + ctf_enum(libcamera, buffer_status, uint32_t, buf_status, buf->metadata().status) + ) +) + + + + +#endif /* INCLUDE_LIBCAMERA_INTERNAL_TRACEPOINTS_TP_H */ + +#include + +#endif /* HAVE_TRACING */ \ No newline at end of file diff --git a/meson_generated/include/libcamera/ipa/core.mojom-module b/meson_generated/include/libcamera/ipa/core.mojom-module new file mode 100644 index 0000000000000000000000000000000000000000..23d006804486981910550f1be9d36024e3bc39df GIT binary patch literal 10199 zcmd5?|BEC?6`!4NJ74bBUGL7^#UojQczY1{5)+QNM%T-QC1Ee)W*348andtWGu3@P z-E;kAvlj>`2Hn+C19reaLh{2AG;+o$1~pzpg8@YpMS_ImkV8XI@CV=P>Yo1gI%ela zatmEMUG;fYuc|)p)vK!hV)?n(P89qfd!SFlE zZ;4skvD~g>dyjidydbJu{;L-?YL8gg6SwZHjB8jvYZ{Ja>JJ-z^ATkPng%NKl4y<; ziy2P)ylV8kmT0PW+i-PV=|GS6#DdMCxYzEnzG|qBY8rmW8j-r5m`m4QMs=|+Lvhq? z);10OBG%P)ZO0t8ZDy&8u0F*q$gK8NruVQjqQVS!=>MvBO~ZB+!|$YMD2`*P9oJ#D zY}`Jtj<%T9gZEw0z_*8((u3-DT~}0L_|CJQCk~}%3G+R1V8bs?4_Z|Ys>kQVL0LgN zQtY-wPFpqFrqxpoMaTcp?Bkx>5tYtGR1o@6+h ZV*gglIk{UvcoGS(*(%-g-ea zpxrD;kn=M1OHS~^}})1w|wTUJxJ(Xi^`^<^rJVV^g>+e4O2C! zk*)*GvPlzpoNT>UXcciB4HXlUp#)g|?wkHhe^qFDtZ z&IaT}(#(S0Dz5H$Eq+G}rsRAu70|#%Y=E2G;@j&p{7DI5@p(_0mhC1cx`$)7g!GmM zmF$72_}1fbT~t74wgbvQI|VUkTI#?z9SHy@VY{8sp1@}u(^Uh^x4n)1O;`aGmTmAF z-g;To!G8>lA^0tPtD613&ERK2lsc;azc~aejZ6%>{^g+SU*S9atI%WY^=^yrwfNUs z{OjvwF5vkFJl_OWzqMX)I}CZe#Gm2MGRbD_ZtVdu^Q0*^z-5k<9(aU-x93yo83hEM z3mW{6pEp4Ue|EBJ7-4lqu(~2x-8^`XwAIbW3A}|Pob?oCnV+O@#HPxVY7bUA$*2oK z$AO=2mY+z2kZv(PRyk7#98AY2<>kppc}bEon(7x}s(s>7Q(cIrI>wHd_s5P``IRv{ zk~7XsB6seI^dj~{{(Dx$6 z&UsSg-yl)~krE|xI1-V*ODoM33R(q|SxoAX#?|`BPCbX~*%^0bM&~ z$Jqs7|Awr64kjvP%i0$(Z@Xg)dq|_gzR0E_Ml+^u^R1ih} z6(qDbG5H%NZ((v3lWUm#9h2*r`~#D>F?k1)yafqso6KdW7NktnI6;Qrt*L0^kIi&y z!U3L2O%n`AM#P`#n@1a@+|8p6a{uPh290nk+W3|{otn@cOs6LFDU;Pig?dfcIyGVI z^bis1CALlw!#&{kArzywPO-wgu&$`~Vka0>m{uL>iUC&#auZb$l{1#5T#TRd9#K|y zR{Q`#s?eDPQW;NWxgy``}Lq0V>RLWBGIOY-53`s^)^L8n<4{DwO z3GE~#dDKL}`$vX|-jbTA>HDY6eyN%E&~S^!lp#UPIubJ|%%f$~-%GBU)=-JxKTvFx z7f{ksCr+*NIrsz&Yb9uf7l*t^KuYS}r{kC(W-;917F-SEDM-}ZkFz*YbQ8_JLO@DxvbkSmG5jTdS^G73 zaP3!+h?#!8+1IjoF#`cnq}Xo=L~%7SRByx}yZG$_ge;}iDsH0F_pgEO;Ffk+Z?k zu0Wv+pRR~mb%-B3`QKN~$=~pii1e+Z*)???Zn%8EESjIikFr?rLAC4PCTbJB@{l=7 UPjM9ZeoR#TPfO4xyPf6#0xKWe%m4rY literal 0 HcmV?d00001 diff --git a/meson_generated/include/libcamera/ipa/core_ipa_interface.h b/meson_generated/include/libcamera/ipa/core_ipa_interface.h new file mode 100644 index 00000000..6d5e379f --- /dev/null +++ b/meson_generated/include/libcamera/ipa/core_ipa_interface.h @@ -0,0 +1,163 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Google Inc. + * + * libcamera core definitions for Image Processing Algorithms + * + * This file is auto-generated. Do not edit. + */ + +#pragma once + + +#include +#include +#include +#include + +#include +#include +#include + +#include + +namespace libcamera { + + + + + +struct IPACameraSensorInfo +{ +public: +#ifndef __DOXYGEN__ + IPACameraSensorInfo() = default; + + template< + typename T1 = std::string, + typename T2 = uint32_t, + typename T3 = uint32_t, + typename T4 = Size, + typename T5 = Rectangle, + typename T6 = Size, + typename T7 = uint64_t, + typename T8 = uint32_t, + typename T9 = uint32_t, + typename T10 = uint32_t, + typename T11 = uint32_t, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr + > + IPACameraSensorInfo(T1 &&_model, T2 &&_bitsPerPixel, T3 &&_cfaPattern, T4 &&_activeAreaSize, T5 &&_analogCrop, T6 &&_outputSize, T7 &&_pixelRate, T8 &&_minLineLength, T9 &&_maxLineLength, T10 &&_minFrameLength, T11 &&_maxFrameLength) + : model(std::forward(_model)) + , bitsPerPixel(std::forward(_bitsPerPixel)) + , cfaPattern(std::forward(_cfaPattern)) + , activeAreaSize(std::forward(_activeAreaSize)) + , analogCrop(std::forward(_analogCrop)) + , outputSize(std::forward(_outputSize)) + , pixelRate(std::forward(_pixelRate)) + , minLineLength(std::forward(_minLineLength)) + , maxLineLength(std::forward(_maxLineLength)) + , minFrameLength(std::forward(_minFrameLength)) + , maxFrameLength(std::forward(_maxFrameLength)) + { + } +#endif + + + std::string model; + uint32_t bitsPerPixel{ 0 }; + uint32_t cfaPattern{ 0 }; + Size activeAreaSize; + Rectangle analogCrop; + Size outputSize; + uint64_t pixelRate{ 0 }; + uint32_t minLineLength{ 0 }; + uint32_t maxLineLength{ 0 }; + uint32_t minFrameLength{ 0 }; + uint32_t maxFrameLength{ 0 }; +}; + +struct IPABuffer +{ +public: +#ifndef __DOXYGEN__ + IPABuffer() = default; + + template< + typename T1 = uint32_t, + typename T2 = std::vector, + std::enable_if_t> * = nullptr, + std::enable_if_t>> * = nullptr + > + IPABuffer(T1 &&_id, T2 &&_planes) + : id(std::forward(_id)) + , planes(std::forward(_planes)) + { + } +#endif + + + uint32_t id{ 0 }; + std::vector planes; +}; + +struct IPASettings +{ +public: +#ifndef __DOXYGEN__ + IPASettings() = default; + + template< + typename T1 = std::string, + typename T2 = std::string, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr + > + IPASettings(T1 &&_configurationFile, T2 &&_sensorModel) + : configurationFile(std::forward(_configurationFile)) + , sensorModel(std::forward(_sensorModel)) + { + } +#endif + + + std::string configurationFile; + std::string sensorModel; +}; + +struct IPAStream +{ +public: +#ifndef __DOXYGEN__ + IPAStream() = default; + + template< + typename T1 = uint32_t, + typename T2 = Size, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr + > + IPAStream(T1 &&_pixelFormat, T2 &&_size) + : pixelFormat(std::forward(_pixelFormat)) + , size(std::forward(_size)) + { + } +#endif + + + uint32_t pixelFormat{ 0 }; + Size size; +}; + + +} /* namespace libcamera */ \ No newline at end of file diff --git a/meson_generated/include/libcamera/ipa/core_ipa_serializer.h b/meson_generated/include/libcamera/ipa/core_ipa_serializer.h new file mode 100644 index 00000000..272c78ea --- /dev/null +++ b/meson_generated/include/libcamera/ipa/core_ipa_serializer.h @@ -0,0 +1,1046 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Google Inc. + * + * Data serializer for core libcamera definitions for IPA + * + * This file is auto-generated. Do not edit. + */ + +#pragma once + +#include +#include + +#include + +#include "libcamera/internal/control_serializer.h" +#include "libcamera/internal/ipa_data_serializer.h" + +namespace libcamera { + +LOG_DECLARE_CATEGORY(IPADataSerializer) + +template<> +class IPADataSerializer +{ +public: + static std::tuple, std::vector> + serialize(const libcamera::Point &data, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + std::vector retData; + + std::vector x; + std::tie(x, std::ignore) = + IPADataSerializer::serialize(data.x); + retData.insert(retData.end(), x.begin(), x.end()); + + std::vector y; + std::tie(y, std::ignore) = + IPADataSerializer::serialize(data.y); + retData.insert(retData.end(), y.begin(), y.end()); + + return {retData, {}}; + } + + static libcamera::Point + deserialize(std::vector &data, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), cs); + } + + + static libcamera::Point + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + libcamera::Point ret; + std::vector::const_iterator m = dataBegin; + + size_t dataSize = std::distance(dataBegin, dataEnd); + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "x" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.x = IPADataSerializer::deserialize(m, m + 4); + m += 4; + dataSize -= 4; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "y" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.y = IPADataSerializer::deserialize(m, m + 4); + + return ret; + } + + static libcamera::Point + deserialize(std::vector &data, + [[maybe_unused]] std::vector &fds, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), cs); + } + + static libcamera::Point + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + [[maybe_unused]] std::vector::const_iterator fdsBegin, + [[maybe_unused]] std::vector::const_iterator fdsEnd, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(dataBegin, dataEnd, cs); + } +}; + +template<> +class IPADataSerializer +{ +public: + static std::tuple, std::vector> + serialize(const libcamera::Size &data, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + std::vector retData; + + std::vector width; + std::tie(width, std::ignore) = + IPADataSerializer::serialize(data.width); + retData.insert(retData.end(), width.begin(), width.end()); + + std::vector height; + std::tie(height, std::ignore) = + IPADataSerializer::serialize(data.height); + retData.insert(retData.end(), height.begin(), height.end()); + + return {retData, {}}; + } + + static libcamera::Size + deserialize(std::vector &data, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), cs); + } + + + static libcamera::Size + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + libcamera::Size ret; + std::vector::const_iterator m = dataBegin; + + size_t dataSize = std::distance(dataBegin, dataEnd); + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "width" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.width = IPADataSerializer::deserialize(m, m + 4); + m += 4; + dataSize -= 4; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "height" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.height = IPADataSerializer::deserialize(m, m + 4); + + return ret; + } + + static libcamera::Size + deserialize(std::vector &data, + [[maybe_unused]] std::vector &fds, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), cs); + } + + static libcamera::Size + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + [[maybe_unused]] std::vector::const_iterator fdsBegin, + [[maybe_unused]] std::vector::const_iterator fdsEnd, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(dataBegin, dataEnd, cs); + } +}; + +template<> +class IPADataSerializer +{ +public: + static std::tuple, std::vector> + serialize(const libcamera::SizeRange &data, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + std::vector retData; + + std::vector min; + std::tie(min, std::ignore) = + IPADataSerializer::serialize(data.min, cs); + appendPOD(retData, min.size()); + retData.insert(retData.end(), min.begin(), min.end()); + + std::vector max; + std::tie(max, std::ignore) = + IPADataSerializer::serialize(data.max, cs); + appendPOD(retData, max.size()); + retData.insert(retData.end(), max.begin(), max.end()); + + std::vector hStep; + std::tie(hStep, std::ignore) = + IPADataSerializer::serialize(data.hStep); + retData.insert(retData.end(), hStep.begin(), hStep.end()); + + std::vector vStep; + std::tie(vStep, std::ignore) = + IPADataSerializer::serialize(data.vStep); + retData.insert(retData.end(), vStep.begin(), vStep.end()); + + return {retData, {}}; + } + + static libcamera::SizeRange + deserialize(std::vector &data, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), cs); + } + + + static libcamera::SizeRange + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + libcamera::SizeRange ret; + std::vector::const_iterator m = dataBegin; + + size_t dataSize = std::distance(dataBegin, dataEnd); + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "minSize" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + const size_t minSize = readPOD(m, 0, dataEnd); + m += 4; + dataSize -= 4; + if (dataSize < minSize) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "min" + << ": not enough data, expected " + << (minSize) << ", got " << (dataSize); + return ret; + } + ret.min = + IPADataSerializer::deserialize(m, m + minSize, cs); + m += minSize; + dataSize -= minSize; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "maxSize" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + const size_t maxSize = readPOD(m, 0, dataEnd); + m += 4; + dataSize -= 4; + if (dataSize < maxSize) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "max" + << ": not enough data, expected " + << (maxSize) << ", got " << (dataSize); + return ret; + } + ret.max = + IPADataSerializer::deserialize(m, m + maxSize, cs); + m += maxSize; + dataSize -= maxSize; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "hStep" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.hStep = IPADataSerializer::deserialize(m, m + 4); + m += 4; + dataSize -= 4; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "vStep" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.vStep = IPADataSerializer::deserialize(m, m + 4); + + return ret; + } + + static libcamera::SizeRange + deserialize(std::vector &data, + [[maybe_unused]] std::vector &fds, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), cs); + } + + static libcamera::SizeRange + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + [[maybe_unused]] std::vector::const_iterator fdsBegin, + [[maybe_unused]] std::vector::const_iterator fdsEnd, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(dataBegin, dataEnd, cs); + } +}; + +template<> +class IPADataSerializer +{ +public: + static std::tuple, std::vector> + serialize(const libcamera::Rectangle &data, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + std::vector retData; + + std::vector x; + std::tie(x, std::ignore) = + IPADataSerializer::serialize(data.x); + retData.insert(retData.end(), x.begin(), x.end()); + + std::vector y; + std::tie(y, std::ignore) = + IPADataSerializer::serialize(data.y); + retData.insert(retData.end(), y.begin(), y.end()); + + std::vector width; + std::tie(width, std::ignore) = + IPADataSerializer::serialize(data.width); + retData.insert(retData.end(), width.begin(), width.end()); + + std::vector height; + std::tie(height, std::ignore) = + IPADataSerializer::serialize(data.height); + retData.insert(retData.end(), height.begin(), height.end()); + + return {retData, {}}; + } + + static libcamera::Rectangle + deserialize(std::vector &data, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), cs); + } + + + static libcamera::Rectangle + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + libcamera::Rectangle ret; + std::vector::const_iterator m = dataBegin; + + size_t dataSize = std::distance(dataBegin, dataEnd); + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "x" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.x = IPADataSerializer::deserialize(m, m + 4); + m += 4; + dataSize -= 4; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "y" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.y = IPADataSerializer::deserialize(m, m + 4); + m += 4; + dataSize -= 4; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "width" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.width = IPADataSerializer::deserialize(m, m + 4); + m += 4; + dataSize -= 4; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "height" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.height = IPADataSerializer::deserialize(m, m + 4); + + return ret; + } + + static libcamera::Rectangle + deserialize(std::vector &data, + [[maybe_unused]] std::vector &fds, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), cs); + } + + static libcamera::Rectangle + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + [[maybe_unused]] std::vector::const_iterator fdsBegin, + [[maybe_unused]] std::vector::const_iterator fdsEnd, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(dataBegin, dataEnd, cs); + } +}; + +template<> +class IPADataSerializer +{ +public: + static std::tuple, std::vector> + serialize(const libcamera::IPACameraSensorInfo &data, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + std::vector retData; + + std::vector model; + std::tie(model, std::ignore) = + IPADataSerializer::serialize(data.model); + appendPOD(retData, model.size()); + retData.insert(retData.end(), model.begin(), model.end()); + + std::vector bitsPerPixel; + std::tie(bitsPerPixel, std::ignore) = + IPADataSerializer::serialize(data.bitsPerPixel); + retData.insert(retData.end(), bitsPerPixel.begin(), bitsPerPixel.end()); + + std::vector cfaPattern; + std::tie(cfaPattern, std::ignore) = + IPADataSerializer::serialize(data.cfaPattern); + retData.insert(retData.end(), cfaPattern.begin(), cfaPattern.end()); + + std::vector activeAreaSize; + std::tie(activeAreaSize, std::ignore) = + IPADataSerializer::serialize(data.activeAreaSize, cs); + appendPOD(retData, activeAreaSize.size()); + retData.insert(retData.end(), activeAreaSize.begin(), activeAreaSize.end()); + + std::vector analogCrop; + std::tie(analogCrop, std::ignore) = + IPADataSerializer::serialize(data.analogCrop, cs); + appendPOD(retData, analogCrop.size()); + retData.insert(retData.end(), analogCrop.begin(), analogCrop.end()); + + std::vector outputSize; + std::tie(outputSize, std::ignore) = + IPADataSerializer::serialize(data.outputSize, cs); + appendPOD(retData, outputSize.size()); + retData.insert(retData.end(), outputSize.begin(), outputSize.end()); + + std::vector pixelRate; + std::tie(pixelRate, std::ignore) = + IPADataSerializer::serialize(data.pixelRate); + retData.insert(retData.end(), pixelRate.begin(), pixelRate.end()); + + std::vector minLineLength; + std::tie(minLineLength, std::ignore) = + IPADataSerializer::serialize(data.minLineLength); + retData.insert(retData.end(), minLineLength.begin(), minLineLength.end()); + + std::vector maxLineLength; + std::tie(maxLineLength, std::ignore) = + IPADataSerializer::serialize(data.maxLineLength); + retData.insert(retData.end(), maxLineLength.begin(), maxLineLength.end()); + + std::vector minFrameLength; + std::tie(minFrameLength, std::ignore) = + IPADataSerializer::serialize(data.minFrameLength); + retData.insert(retData.end(), minFrameLength.begin(), minFrameLength.end()); + + std::vector maxFrameLength; + std::tie(maxFrameLength, std::ignore) = + IPADataSerializer::serialize(data.maxFrameLength); + retData.insert(retData.end(), maxFrameLength.begin(), maxFrameLength.end()); + + return {retData, {}}; + } + + static libcamera::IPACameraSensorInfo + deserialize(std::vector &data, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), cs); + } + + + static libcamera::IPACameraSensorInfo + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + libcamera::IPACameraSensorInfo ret; + std::vector::const_iterator m = dataBegin; + + size_t dataSize = std::distance(dataBegin, dataEnd); + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "modelSize" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + const size_t modelSize = readPOD(m, 0, dataEnd); + m += 4; + dataSize -= 4; + if (dataSize < modelSize) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "model" + << ": not enough data, expected " + << (modelSize) << ", got " << (dataSize); + return ret; + } + ret.model = + IPADataSerializer::deserialize(m, m + modelSize); + m += modelSize; + dataSize -= modelSize; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "bitsPerPixel" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.bitsPerPixel = IPADataSerializer::deserialize(m, m + 4); + m += 4; + dataSize -= 4; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "cfaPattern" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.cfaPattern = IPADataSerializer::deserialize(m, m + 4); + m += 4; + dataSize -= 4; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "activeAreaSizeSize" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + const size_t activeAreaSizeSize = readPOD(m, 0, dataEnd); + m += 4; + dataSize -= 4; + if (dataSize < activeAreaSizeSize) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "activeAreaSize" + << ": not enough data, expected " + << (activeAreaSizeSize) << ", got " << (dataSize); + return ret; + } + ret.activeAreaSize = + IPADataSerializer::deserialize(m, m + activeAreaSizeSize, cs); + m += activeAreaSizeSize; + dataSize -= activeAreaSizeSize; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "analogCropSize" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + const size_t analogCropSize = readPOD(m, 0, dataEnd); + m += 4; + dataSize -= 4; + if (dataSize < analogCropSize) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "analogCrop" + << ": not enough data, expected " + << (analogCropSize) << ", got " << (dataSize); + return ret; + } + ret.analogCrop = + IPADataSerializer::deserialize(m, m + analogCropSize, cs); + m += analogCropSize; + dataSize -= analogCropSize; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "outputSizeSize" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + const size_t outputSizeSize = readPOD(m, 0, dataEnd); + m += 4; + dataSize -= 4; + if (dataSize < outputSizeSize) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "outputSize" + << ": not enough data, expected " + << (outputSizeSize) << ", got " << (dataSize); + return ret; + } + ret.outputSize = + IPADataSerializer::deserialize(m, m + outputSizeSize, cs); + m += outputSizeSize; + dataSize -= outputSizeSize; + + + if (dataSize < 8) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "pixelRate" + << ": not enough data, expected " + << (8) << ", got " << (dataSize); + return ret; + } + ret.pixelRate = IPADataSerializer::deserialize(m, m + 8); + m += 8; + dataSize -= 8; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "minLineLength" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.minLineLength = IPADataSerializer::deserialize(m, m + 4); + m += 4; + dataSize -= 4; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "maxLineLength" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.maxLineLength = IPADataSerializer::deserialize(m, m + 4); + m += 4; + dataSize -= 4; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "minFrameLength" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.minFrameLength = IPADataSerializer::deserialize(m, m + 4); + m += 4; + dataSize -= 4; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "maxFrameLength" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.maxFrameLength = IPADataSerializer::deserialize(m, m + 4); + + return ret; + } + + static libcamera::IPACameraSensorInfo + deserialize(std::vector &data, + [[maybe_unused]] std::vector &fds, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), cs); + } + + static libcamera::IPACameraSensorInfo + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + [[maybe_unused]] std::vector::const_iterator fdsBegin, + [[maybe_unused]] std::vector::const_iterator fdsEnd, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(dataBegin, dataEnd, cs); + } +}; + +template<> +class IPADataSerializer +{ +public: + static std::tuple, std::vector> + serialize(const libcamera::IPABuffer &data, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + std::vector retData; + std::vector retFds; + + std::vector id; + std::tie(id, std::ignore) = + IPADataSerializer::serialize(data.id); + retData.insert(retData.end(), id.begin(), id.end()); + + std::vector planes; + std::vector planesFds; + std::tie(planes, planesFds) = + IPADataSerializer>::serialize(data.planes, cs); + appendPOD(retData, planes.size()); + appendPOD(retData, planesFds.size()); + retData.insert(retData.end(), planes.begin(), planes.end()); + retFds.insert(retFds.end(), planesFds.begin(), planesFds.end()); + + return {retData, retFds}; + } + + static libcamera::IPABuffer + deserialize(std::vector &data, + std::vector &fds, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), fds.cbegin(), fds.cend(), cs); + } + + + static libcamera::IPABuffer + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + std::vector::const_iterator fdsBegin, + std::vector::const_iterator fdsEnd, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + libcamera::IPABuffer ret; + std::vector::const_iterator m = dataBegin; + std::vector::const_iterator n = fdsBegin; + + size_t dataSize = std::distance(dataBegin, dataEnd); + [[maybe_unused]] size_t fdsSize = std::distance(fdsBegin, fdsEnd); + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "id" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.id = IPADataSerializer::deserialize(m, m + 4); + m += 4; + dataSize -= 4; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "planesSize" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + const size_t planesSize = readPOD(m, 0, dataEnd); + m += 4; + dataSize -= 4; + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "planesFdsSize" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + const size_t planesFdsSize = readPOD(m, 0, dataEnd); + m += 4; + dataSize -= 4; + if (fdsSize < planesFdsSize) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "planes" + << ": not enough fds, expected " + << (planesFdsSize) << ", got " << (fdsSize); + return ret; + } + if (dataSize < planesSize) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "planes" + << ": not enough data, expected " + << (planesSize) << ", got " << (dataSize); + return ret; + } + ret.planes = + IPADataSerializer>::deserialize(m, m + planesSize, n, n + planesFdsSize, cs); + + return ret; + } +}; + +template<> +class IPADataSerializer +{ +public: + static std::tuple, std::vector> + serialize(const libcamera::IPASettings &data, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + std::vector retData; + + std::vector configurationFile; + std::tie(configurationFile, std::ignore) = + IPADataSerializer::serialize(data.configurationFile); + appendPOD(retData, configurationFile.size()); + retData.insert(retData.end(), configurationFile.begin(), configurationFile.end()); + + std::vector sensorModel; + std::tie(sensorModel, std::ignore) = + IPADataSerializer::serialize(data.sensorModel); + appendPOD(retData, sensorModel.size()); + retData.insert(retData.end(), sensorModel.begin(), sensorModel.end()); + + return {retData, {}}; + } + + static libcamera::IPASettings + deserialize(std::vector &data, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), cs); + } + + + static libcamera::IPASettings + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + libcamera::IPASettings ret; + std::vector::const_iterator m = dataBegin; + + size_t dataSize = std::distance(dataBegin, dataEnd); + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "configurationFileSize" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + const size_t configurationFileSize = readPOD(m, 0, dataEnd); + m += 4; + dataSize -= 4; + if (dataSize < configurationFileSize) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "configurationFile" + << ": not enough data, expected " + << (configurationFileSize) << ", got " << (dataSize); + return ret; + } + ret.configurationFile = + IPADataSerializer::deserialize(m, m + configurationFileSize); + m += configurationFileSize; + dataSize -= configurationFileSize; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "sensorModelSize" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + const size_t sensorModelSize = readPOD(m, 0, dataEnd); + m += 4; + dataSize -= 4; + if (dataSize < sensorModelSize) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "sensorModel" + << ": not enough data, expected " + << (sensorModelSize) << ", got " << (dataSize); + return ret; + } + ret.sensorModel = + IPADataSerializer::deserialize(m, m + sensorModelSize); + + return ret; + } + + static libcamera::IPASettings + deserialize(std::vector &data, + [[maybe_unused]] std::vector &fds, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), cs); + } + + static libcamera::IPASettings + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + [[maybe_unused]] std::vector::const_iterator fdsBegin, + [[maybe_unused]] std::vector::const_iterator fdsEnd, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(dataBegin, dataEnd, cs); + } +}; + +template<> +class IPADataSerializer +{ +public: + static std::tuple, std::vector> + serialize(const libcamera::IPAStream &data, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + std::vector retData; + + std::vector pixelFormat; + std::tie(pixelFormat, std::ignore) = + IPADataSerializer::serialize(data.pixelFormat); + retData.insert(retData.end(), pixelFormat.begin(), pixelFormat.end()); + + std::vector size; + std::tie(size, std::ignore) = + IPADataSerializer::serialize(data.size, cs); + appendPOD(retData, size.size()); + retData.insert(retData.end(), size.begin(), size.end()); + + return {retData, {}}; + } + + static libcamera::IPAStream + deserialize(std::vector &data, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), cs); + } + + + static libcamera::IPAStream + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + libcamera::IPAStream ret; + std::vector::const_iterator m = dataBegin; + + size_t dataSize = std::distance(dataBegin, dataEnd); + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "pixelFormat" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.pixelFormat = IPADataSerializer::deserialize(m, m + 4); + m += 4; + dataSize -= 4; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "sizeSize" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + const size_t sizeSize = readPOD(m, 0, dataEnd); + m += 4; + dataSize -= 4; + if (dataSize < sizeSize) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "size" + << ": not enough data, expected " + << (sizeSize) << ", got " << (dataSize); + return ret; + } + ret.size = + IPADataSerializer::deserialize(m, m + sizeSize, cs); + + return ret; + } + + static libcamera::IPAStream + deserialize(std::vector &data, + [[maybe_unused]] std::vector &fds, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), cs); + } + + static libcamera::IPAStream + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + [[maybe_unused]] std::vector::const_iterator fdsBegin, + [[maybe_unused]] std::vector::const_iterator fdsEnd, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(dataBegin, dataEnd, cs); + } +}; + + +} /* namespace libcamera */ \ No newline at end of file diff --git a/meson_generated/include/libcamera/ipa/raspberrypi.mojom-module b/meson_generated/include/libcamera/ipa/raspberrypi.mojom-module new file mode 100644 index 0000000000000000000000000000000000000000..62930e1b6c0b6c1f7a130185de8026eb18e8c1b7 GIT binary patch literal 32546 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 Gn)!d28tNke literal 0 HcmV?d00001 diff --git a/meson_generated/include/libcamera/ipa/raspberrypi_ipa_interface.h b/meson_generated/include/libcamera/ipa/raspberrypi_ipa_interface.h new file mode 100644 index 00000000..645040c5 --- /dev/null +++ b/meson_generated/include/libcamera/ipa/raspberrypi_ipa_interface.h @@ -0,0 +1,377 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Google Inc. + * + * Image Processing Algorithm interface for raspberrypi + * + * This file is auto-generated. Do not edit. + */ + +#pragma once + + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +namespace libcamera { + +namespace ipa { + +namespace RPi { + + + +const uint32_t MaxLsGridSize = 0x8000; + + +enum class _RPiCmd { + Exit = 0, + Init = 1, + Start = 2, + Stop = 3, + Configure = 4, + MapBuffers = 5, + UnmapBuffers = 6, + PrepareIsp = 7, + ProcessStats = 8, +}; + +enum class _RPiEventCmd { + PrepareIspComplete = 1, + ProcessStatsComplete = 2, + MetadataReady = 3, + SetIspControls = 4, + SetDelayedControls = 5, + SetLensControls = 6, + SetCameraTimeout = 7, +}; + + +struct SensorConfig +{ +public: +#ifndef __DOXYGEN__ + SensorConfig() = default; + + template< + typename T1 = uint32_t, + std::enable_if_t> * = nullptr + > + SensorConfig(T1 &&_sensorMetadata) + : sensorMetadata(std::forward(_sensorMetadata)) + { + } +#endif + + + uint32_t sensorMetadata{ 0 }; +}; + +struct InitParams +{ +public: +#ifndef __DOXYGEN__ + InitParams() = default; + + template< + typename T1 = bool, + typename T2 = IPACameraSensorInfo, + typename T3 = float, + typename T4 = SharedFD, + typename T5 = SharedFD, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr + > + InitParams(T1 &&_lensPresent, T2 &&_sensorInfo, T3 &&_controllerMinFrameDurationUs, T4 &&_fe, T5 &&_be) + : lensPresent(std::forward(_lensPresent)) + , sensorInfo(std::forward(_sensorInfo)) + , controllerMinFrameDurationUs(std::forward(_controllerMinFrameDurationUs)) + , fe(std::forward(_fe)) + , be(std::forward(_be)) + { + } +#endif + + + bool lensPresent{ 0 }; + IPACameraSensorInfo sensorInfo; + float controllerMinFrameDurationUs{ 0 }; + SharedFD fe{ -1 }; + SharedFD be{ -1 }; +}; + +struct InitResult +{ +public: +#ifndef __DOXYGEN__ + InitResult() = default; + + template< + typename T1 = SensorConfig, + typename T2 = ControlInfoMap, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr + > + InitResult(T1 &&_sensorConfig, T2 &&_controlInfo) + : sensorConfig(std::forward(_sensorConfig)) + , controlInfo(std::forward(_controlInfo)) + { + } +#endif + + + SensorConfig sensorConfig; + ControlInfoMap controlInfo; +}; + +struct BufferIds +{ +public: +#ifndef __DOXYGEN__ + BufferIds() = default; + + template< + typename T1 = uint32_t, + typename T2 = uint32_t, + typename T3 = uint32_t, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr + > + BufferIds(T1 &&_bayer, T2 &&_embedded, T3 &&_stats) + : bayer(std::forward(_bayer)) + , embedded(std::forward(_embedded)) + , stats(std::forward(_stats)) + { + } +#endif + + + uint32_t bayer{ 0 }; + uint32_t embedded{ 0 }; + uint32_t stats{ 0 }; +}; + +struct ConfigParams +{ +public: +#ifndef __DOXYGEN__ + ConfigParams() = default; + + template< + typename T1 = uint32_t, + typename T2 = ControlInfoMap, + typename T3 = ControlInfoMap, + typename T4 = ControlInfoMap, + typename T5 = SharedFD, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr + > + ConfigParams(T1 &&_transform, T2 &&_sensorControls, T3 &&_ispControls, T4 &&_lensControls, T5 &&_lsTableHandle) + : transform(std::forward(_transform)) + , sensorControls(std::forward(_sensorControls)) + , ispControls(std::forward(_ispControls)) + , lensControls(std::forward(_lensControls)) + , lsTableHandle(std::forward(_lsTableHandle)) + { + } +#endif + + + uint32_t transform{ 0 }; + ControlInfoMap sensorControls; + ControlInfoMap ispControls; + ControlInfoMap lensControls; + SharedFD lsTableHandle{ -1 }; +}; + +struct ConfigResult +{ +public: +#ifndef __DOXYGEN__ + ConfigResult() = default; + + template< + typename T1 = float, + typename T2 = ControlInfoMap, + typename T3 = ControlList, + typename T4 = ControlList, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr + > + ConfigResult(T1 &&_modeSensitivity, T2 &&_controlInfo, T3 &&_sensorControls, T4 &&_lensControls) + : modeSensitivity(std::forward(_modeSensitivity)) + , controlInfo(std::forward(_controlInfo)) + , sensorControls(std::forward(_sensorControls)) + , lensControls(std::forward(_lensControls)) + { + } +#endif + + + float modeSensitivity{ 0 }; + ControlInfoMap controlInfo; + ControlList sensorControls; + ControlList lensControls; +}; + +struct StartResult +{ +public: +#ifndef __DOXYGEN__ + StartResult() = default; + + template< + typename T1 = ControlList, + typename T2 = int32_t, + typename T3 = int32_t, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr + > + StartResult(T1 &&_controls, T2 &&_startupFrameCount, T3 &&_invalidFrameCount) + : controls(std::forward(_controls)) + , startupFrameCount(std::forward(_startupFrameCount)) + , invalidFrameCount(std::forward(_invalidFrameCount)) + { + } +#endif + + + ControlList controls; + int32_t startupFrameCount{ 0 }; + int32_t invalidFrameCount{ 0 }; +}; + +struct PrepareParams +{ +public: +#ifndef __DOXYGEN__ + PrepareParams() = default; + + template< + typename T1 = BufferIds, + typename T2 = ControlList, + typename T3 = ControlList, + typename T4 = uint32_t, + typename T5 = uint32_t, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr + > + PrepareParams(T1 &&_buffers, T2 &&_sensorControls, T3 &&_requestControls, T4 &&_ipaContext, T5 &&_delayContext) + : buffers(std::forward(_buffers)) + , sensorControls(std::forward(_sensorControls)) + , requestControls(std::forward(_requestControls)) + , ipaContext(std::forward(_ipaContext)) + , delayContext(std::forward(_delayContext)) + { + } +#endif + + + BufferIds buffers; + ControlList sensorControls; + ControlList requestControls; + uint32_t ipaContext{ 0 }; + uint32_t delayContext{ 0 }; +}; + +struct ProcessParams +{ +public: +#ifndef __DOXYGEN__ + ProcessParams() = default; + + template< + typename T1 = BufferIds, + typename T2 = uint32_t, + std::enable_if_t> * = nullptr, + std::enable_if_t> * = nullptr + > + ProcessParams(T1 &&_buffers, T2 &&_ipaContext) + : buffers(std::forward(_buffers)) + , ipaContext(std::forward(_ipaContext)) + { + } +#endif + + + BufferIds buffers; + uint32_t ipaContext{ 0 }; +}; + +class IPARPiInterface : public IPAInterface +{ +public: + + virtual int32_t init( + const IPASettings &settings, + const InitParams ¶ms, + InitResult *result) = 0; + + virtual void start( + const ControlList &controls, + StartResult *result) = 0; + + virtual void stop() = 0; + + virtual int32_t configure( + const IPACameraSensorInfo &sensorInfo, + const ConfigParams ¶ms, + ConfigResult *result) = 0; + + virtual void mapBuffers( + const std::vector &buffers) = 0; + + virtual void unmapBuffers( + const std::vector &ids) = 0; + + virtual void prepareIsp( + const PrepareParams ¶ms) = 0; + + virtual void processStats( + const ProcessParams ¶ms) = 0; + + Signal prepareIspComplete; + + Signal processStatsComplete; + + Signal metadataReady; + + Signal setIspControls; + + Signal setDelayedControls; + + Signal setLensControls; + + Signal setCameraTimeout; +}; + +} /* namespace RPi */ + +} /* namespace ipa */ + +} /* namespace libcamera */ \ No newline at end of file diff --git a/meson_generated/include/libcamera/ipa/raspberrypi_ipa_proxy.h b/meson_generated/include/libcamera/ipa/raspberrypi_ipa_proxy.h new file mode 100644 index 00000000..1235fc64 --- /dev/null +++ b/meson_generated/include/libcamera/ipa/raspberrypi_ipa_proxy.h @@ -0,0 +1,239 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Google Inc. + * + * Image Processing Algorithm proxy for raspberrypi + * + * This file is auto-generated. Do not edit. + */ + +#pragma once + +#include +#include + +#include +#include + +#include "libcamera/internal/control_serializer.h" +#include "libcamera/internal/ipa_proxy.h" +#include "libcamera/internal/ipc_pipe.h" +#include "libcamera/internal/ipc_pipe_unixsocket.h" +#include "libcamera/internal/ipc_unixsocket.h" + +namespace libcamera { + +namespace ipa { + +namespace RPi { + + +class IPAProxyRPiThreaded; +class IPAProxyRPiIsolated; + +class IPAProxyRPi : public IPAProxy, public IPARPiInterface, public Object +{ +public: + using Threaded = IPAProxyRPiThreaded; + using Isolated = IPAProxyRPiIsolated; + +protected: + using IPAProxy::IPAProxy; +}; + +class IPAProxyRPiThreaded : public IPAProxyRPi +{ +public: + IPAProxyRPiThreaded(IPAModule *ipam, const CameraManager &cm); + ~IPAProxyRPiThreaded(); + + + int32_t init( + const IPASettings &settings, + const InitParams ¶ms, + InitResult *result) override; + + void start( + const ControlList &controls, + StartResult *result) override; + + void stop() override; + + int32_t configure( + const IPACameraSensorInfo &sensorInfo, + const ConfigParams ¶ms, + ConfigResult *result) override; + + void mapBuffers( + const std::vector &buffers) override; + + void unmapBuffers( + const std::vector &ids) override; + + void prepareIsp( + const PrepareParams ¶ms) override; + + void processStats( + const ProcessParams ¶ms) override; + + +private: + + void prepareIspCompleteHandler( + const BufferIds &buffers, + const bool stitchSwapBuffers); + + void processStatsCompleteHandler( + const BufferIds &buffers); + + void metadataReadyHandler( + const ControlList &metadata); + + void setIspControlsHandler( + const ControlList &controls); + + void setDelayedControlsHandler( + const ControlList &controls, + const uint32_t delayContext); + + void setLensControlsHandler( + const ControlList &controls); + + void setCameraTimeoutHandler( + const uint32_t maxFrameLengthMs); + + + /* Helper class to invoke async functions in another thread. */ + class ThreadProxy : public Object + { + public: + ThreadProxy() + : ipa_(nullptr) + { + } + + void setIPA(IPARPiInterface *ipa) + { + ipa_ = ipa; + } + + void stop() + { + ipa_->stop(); + } + + void start( + const ControlList &controls, + StartResult *result) + { + ipa_->start(controls, result); + } + void prepareIsp( + const PrepareParams ¶ms) + { + ipa_->prepareIsp(params); + } + void processStats( + const ProcessParams ¶ms) + { + ipa_->processStats(params); + } + + private: + IPARPiInterface *ipa_; + }; + + Thread thread_; + ThreadProxy proxy_; + std::unique_ptr ipa_; +}; + +class IPAProxyRPiIsolated : public IPAProxyRPi +{ +public: + IPAProxyRPiIsolated(IPAModule *ipam, const CameraManager &cm); + ~IPAProxyRPiIsolated(); + + + int32_t init( + const IPASettings &settings, + const InitParams ¶ms, + InitResult *result) override; + + void start( + const ControlList &controls, + StartResult *result) override; + + void stop() override; + + int32_t configure( + const IPACameraSensorInfo &sensorInfo, + const ConfigParams ¶ms, + ConfigResult *result) override; + + void mapBuffers( + const std::vector &buffers) override; + + void unmapBuffers( + const std::vector &ids) override; + + void prepareIsp( + const PrepareParams ¶ms) override; + + void processStats( + const ProcessParams ¶ms) override; + + +private: + void recvMessage(const IPCMessage &data); + + + void prepareIspCompleteHandler( + std::vector::const_iterator data, + size_t dataSize, + const std::vector &fds); + + void processStatsCompleteHandler( + std::vector::const_iterator data, + size_t dataSize, + const std::vector &fds); + + void metadataReadyHandler( + std::vector::const_iterator data, + size_t dataSize, + const std::vector &fds); + + void setIspControlsHandler( + std::vector::const_iterator data, + size_t dataSize, + const std::vector &fds); + + void setDelayedControlsHandler( + std::vector::const_iterator data, + size_t dataSize, + const std::vector &fds); + + void setLensControlsHandler( + std::vector::const_iterator data, + size_t dataSize, + const std::vector &fds); + + void setCameraTimeoutHandler( + std::vector::const_iterator data, + size_t dataSize, + const std::vector &fds); + + + std::unique_ptr ipc_; + + ControlSerializer controlSerializer_; + + + uint32_t seq_; +}; + +} /* namespace RPi */ + +} /* namespace ipa */ + +} /* namespace libcamera */ \ No newline at end of file diff --git a/meson_generated/include/libcamera/ipa/raspberrypi_ipa_serializer.h b/meson_generated/include/libcamera/ipa/raspberrypi_ipa_serializer.h new file mode 100644 index 00000000..45aee50e --- /dev/null +++ b/meson_generated/include/libcamera/ipa/raspberrypi_ipa_serializer.h @@ -0,0 +1,1188 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Google Inc. + * + * Image Processing Algorithm data serializer for raspberrypi + * + * This file is auto-generated. Do not edit. + */ + +#pragma once + +#include +#include + +#include +#include + +#include "libcamera/internal/control_serializer.h" +#include "libcamera/internal/ipa_data_serializer.h" + +namespace libcamera { + +LOG_DECLARE_CATEGORY(IPADataSerializer) + +template<> +class IPADataSerializer +{ +public: + static std::tuple, std::vector> + serialize(const ipa::RPi::SensorConfig &data, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + std::vector retData; + + std::vector sensorMetadata; + std::tie(sensorMetadata, std::ignore) = + IPADataSerializer::serialize(data.sensorMetadata); + retData.insert(retData.end(), sensorMetadata.begin(), sensorMetadata.end()); + + return {retData, {}}; + } + + static ipa::RPi::SensorConfig + deserialize(std::vector &data, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), cs); + } + + + static ipa::RPi::SensorConfig + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + ipa::RPi::SensorConfig ret; + std::vector::const_iterator m = dataBegin; + + size_t dataSize = std::distance(dataBegin, dataEnd); + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "sensorMetadata" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.sensorMetadata = IPADataSerializer::deserialize(m, m + 4); + + return ret; + } + + static ipa::RPi::SensorConfig + deserialize(std::vector &data, + [[maybe_unused]] std::vector &fds, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), cs); + } + + static ipa::RPi::SensorConfig + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + [[maybe_unused]] std::vector::const_iterator fdsBegin, + [[maybe_unused]] std::vector::const_iterator fdsEnd, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(dataBegin, dataEnd, cs); + } +}; + +template<> +class IPADataSerializer +{ +public: + static std::tuple, std::vector> + serialize(const ipa::RPi::InitParams &data, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + std::vector retData; + std::vector retFds; + + std::vector lensPresent; + std::tie(lensPresent, std::ignore) = + IPADataSerializer::serialize(data.lensPresent); + retData.insert(retData.end(), lensPresent.begin(), lensPresent.end()); + + std::vector sensorInfo; + std::tie(sensorInfo, std::ignore) = + IPADataSerializer::serialize(data.sensorInfo, cs); + appendPOD(retData, sensorInfo.size()); + retData.insert(retData.end(), sensorInfo.begin(), sensorInfo.end()); + + std::vector controllerMinFrameDurationUs; + std::tie(controllerMinFrameDurationUs, std::ignore) = + IPADataSerializer::serialize(data.controllerMinFrameDurationUs); + retData.insert(retData.end(), controllerMinFrameDurationUs.begin(), controllerMinFrameDurationUs.end()); + + std::vector fe; + std::vector feFds; + std::tie(fe, feFds) = + IPADataSerializer::serialize(data.fe); + retData.insert(retData.end(), fe.begin(), fe.end()); + retFds.insert(retFds.end(), feFds.begin(), feFds.end()); + + std::vector be; + std::vector beFds; + std::tie(be, beFds) = + IPADataSerializer::serialize(data.be); + retData.insert(retData.end(), be.begin(), be.end()); + retFds.insert(retFds.end(), beFds.begin(), beFds.end()); + + return {retData, retFds}; + } + + static ipa::RPi::InitParams + deserialize(std::vector &data, + std::vector &fds, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), fds.cbegin(), fds.cend(), cs); + } + + + static ipa::RPi::InitParams + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + std::vector::const_iterator fdsBegin, + std::vector::const_iterator fdsEnd, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + ipa::RPi::InitParams ret; + std::vector::const_iterator m = dataBegin; + std::vector::const_iterator n = fdsBegin; + + size_t dataSize = std::distance(dataBegin, dataEnd); + [[maybe_unused]] size_t fdsSize = std::distance(fdsBegin, fdsEnd); + + if (dataSize < 1) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "lensPresent" + << ": not enough data, expected " + << (1) << ", got " << (dataSize); + return ret; + } + ret.lensPresent = IPADataSerializer::deserialize(m, m + 1); + m += 1; + dataSize -= 1; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "sensorInfoSize" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + const size_t sensorInfoSize = readPOD(m, 0, dataEnd); + m += 4; + dataSize -= 4; + if (dataSize < sensorInfoSize) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "sensorInfo" + << ": not enough data, expected " + << (sensorInfoSize) << ", got " << (dataSize); + return ret; + } + ret.sensorInfo = + IPADataSerializer::deserialize(m, m + sensorInfoSize, cs); + m += sensorInfoSize; + dataSize -= sensorInfoSize; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "controllerMinFrameDurationUs" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.controllerMinFrameDurationUs = IPADataSerializer::deserialize(m, m + 4); + m += 4; + dataSize -= 4; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "fe" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.fe = IPADataSerializer::deserialize(m, m + 4, n, n + 1, cs); + m += 4; + dataSize -= 4; + n += ret.fe.isValid() ? 1 : 0; + fdsSize -= ret.fe.isValid() ? 1 : 0; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "be" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.be = IPADataSerializer::deserialize(m, m + 4, n, n + 1, cs); + + return ret; + } +}; + +template<> +class IPADataSerializer +{ +public: + static std::tuple, std::vector> + serialize(const ipa::RPi::InitResult &data, + ControlSerializer *cs) + { + std::vector retData; + + std::vector sensorConfig; + std::tie(sensorConfig, std::ignore) = + IPADataSerializer::serialize(data.sensorConfig, cs); + appendPOD(retData, sensorConfig.size()); + retData.insert(retData.end(), sensorConfig.begin(), sensorConfig.end()); + + if (data.controlInfo.size() > 0) { + std::vector controlInfo; + std::tie(controlInfo, std::ignore) = + IPADataSerializer::serialize(data.controlInfo, cs); + appendPOD(retData, controlInfo.size()); + retData.insert(retData.end(), controlInfo.begin(), controlInfo.end()); + } else { + appendPOD(retData, 0); + } + + return {retData, {}}; + } + + static ipa::RPi::InitResult + deserialize(std::vector &data, + ControlSerializer *cs) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), cs); + } + + + static ipa::RPi::InitResult + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + ControlSerializer *cs) + { + ipa::RPi::InitResult ret; + std::vector::const_iterator m = dataBegin; + + size_t dataSize = std::distance(dataBegin, dataEnd); + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "sensorConfigSize" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + const size_t sensorConfigSize = readPOD(m, 0, dataEnd); + m += 4; + dataSize -= 4; + if (dataSize < sensorConfigSize) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "sensorConfig" + << ": not enough data, expected " + << (sensorConfigSize) << ", got " << (dataSize); + return ret; + } + ret.sensorConfig = + IPADataSerializer::deserialize(m, m + sensorConfigSize, cs); + m += sensorConfigSize; + dataSize -= sensorConfigSize; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "controlInfoSize" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + const size_t controlInfoSize = readPOD(m, 0, dataEnd); + m += 4; + dataSize -= 4; + if (dataSize < controlInfoSize) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "controlInfo" + << ": not enough data, expected " + << (controlInfoSize) << ", got " << (dataSize); + return ret; + } + if (controlInfoSize > 0) + ret.controlInfo = + IPADataSerializer::deserialize(m, m + controlInfoSize, cs); + + return ret; + } + + static ipa::RPi::InitResult + deserialize(std::vector &data, + [[maybe_unused]] std::vector &fds, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), cs); + } + + static ipa::RPi::InitResult + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + [[maybe_unused]] std::vector::const_iterator fdsBegin, + [[maybe_unused]] std::vector::const_iterator fdsEnd, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(dataBegin, dataEnd, cs); + } +}; + +template<> +class IPADataSerializer +{ +public: + static std::tuple, std::vector> + serialize(const ipa::RPi::BufferIds &data, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + std::vector retData; + + std::vector bayer; + std::tie(bayer, std::ignore) = + IPADataSerializer::serialize(data.bayer); + retData.insert(retData.end(), bayer.begin(), bayer.end()); + + std::vector embedded; + std::tie(embedded, std::ignore) = + IPADataSerializer::serialize(data.embedded); + retData.insert(retData.end(), embedded.begin(), embedded.end()); + + std::vector stats; + std::tie(stats, std::ignore) = + IPADataSerializer::serialize(data.stats); + retData.insert(retData.end(), stats.begin(), stats.end()); + + return {retData, {}}; + } + + static ipa::RPi::BufferIds + deserialize(std::vector &data, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), cs); + } + + + static ipa::RPi::BufferIds + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + ipa::RPi::BufferIds ret; + std::vector::const_iterator m = dataBegin; + + size_t dataSize = std::distance(dataBegin, dataEnd); + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "bayer" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.bayer = IPADataSerializer::deserialize(m, m + 4); + m += 4; + dataSize -= 4; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "embedded" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.embedded = IPADataSerializer::deserialize(m, m + 4); + m += 4; + dataSize -= 4; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "stats" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.stats = IPADataSerializer::deserialize(m, m + 4); + + return ret; + } + + static ipa::RPi::BufferIds + deserialize(std::vector &data, + [[maybe_unused]] std::vector &fds, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), cs); + } + + static ipa::RPi::BufferIds + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + [[maybe_unused]] std::vector::const_iterator fdsBegin, + [[maybe_unused]] std::vector::const_iterator fdsEnd, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(dataBegin, dataEnd, cs); + } +}; + +template<> +class IPADataSerializer +{ +public: + static std::tuple, std::vector> + serialize(const ipa::RPi::ConfigParams &data, + ControlSerializer *cs) + { + std::vector retData; + std::vector retFds; + + std::vector transform; + std::tie(transform, std::ignore) = + IPADataSerializer::serialize(data.transform); + retData.insert(retData.end(), transform.begin(), transform.end()); + + if (data.sensorControls.size() > 0) { + std::vector sensorControls; + std::tie(sensorControls, std::ignore) = + IPADataSerializer::serialize(data.sensorControls, cs); + appendPOD(retData, sensorControls.size()); + retData.insert(retData.end(), sensorControls.begin(), sensorControls.end()); + } else { + appendPOD(retData, 0); + } + + if (data.ispControls.size() > 0) { + std::vector ispControls; + std::tie(ispControls, std::ignore) = + IPADataSerializer::serialize(data.ispControls, cs); + appendPOD(retData, ispControls.size()); + retData.insert(retData.end(), ispControls.begin(), ispControls.end()); + } else { + appendPOD(retData, 0); + } + + if (data.lensControls.size() > 0) { + std::vector lensControls; + std::tie(lensControls, std::ignore) = + IPADataSerializer::serialize(data.lensControls, cs); + appendPOD(retData, lensControls.size()); + retData.insert(retData.end(), lensControls.begin(), lensControls.end()); + } else { + appendPOD(retData, 0); + } + + std::vector lsTableHandle; + std::vector lsTableHandleFds; + std::tie(lsTableHandle, lsTableHandleFds) = + IPADataSerializer::serialize(data.lsTableHandle); + retData.insert(retData.end(), lsTableHandle.begin(), lsTableHandle.end()); + retFds.insert(retFds.end(), lsTableHandleFds.begin(), lsTableHandleFds.end()); + + return {retData, retFds}; + } + + static ipa::RPi::ConfigParams + deserialize(std::vector &data, + std::vector &fds, + ControlSerializer *cs) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), fds.cbegin(), fds.cend(), cs); + } + + + static ipa::RPi::ConfigParams + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + std::vector::const_iterator fdsBegin, + std::vector::const_iterator fdsEnd, + ControlSerializer *cs) + { + ipa::RPi::ConfigParams ret; + std::vector::const_iterator m = dataBegin; + std::vector::const_iterator n = fdsBegin; + + size_t dataSize = std::distance(dataBegin, dataEnd); + [[maybe_unused]] size_t fdsSize = std::distance(fdsBegin, fdsEnd); + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "transform" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.transform = IPADataSerializer::deserialize(m, m + 4); + m += 4; + dataSize -= 4; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "sensorControlsSize" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + const size_t sensorControlsSize = readPOD(m, 0, dataEnd); + m += 4; + dataSize -= 4; + if (dataSize < sensorControlsSize) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "sensorControls" + << ": not enough data, expected " + << (sensorControlsSize) << ", got " << (dataSize); + return ret; + } + if (sensorControlsSize > 0) + ret.sensorControls = + IPADataSerializer::deserialize(m, m + sensorControlsSize, cs); + m += sensorControlsSize; + dataSize -= sensorControlsSize; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "ispControlsSize" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + const size_t ispControlsSize = readPOD(m, 0, dataEnd); + m += 4; + dataSize -= 4; + if (dataSize < ispControlsSize) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "ispControls" + << ": not enough data, expected " + << (ispControlsSize) << ", got " << (dataSize); + return ret; + } + if (ispControlsSize > 0) + ret.ispControls = + IPADataSerializer::deserialize(m, m + ispControlsSize, cs); + m += ispControlsSize; + dataSize -= ispControlsSize; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "lensControlsSize" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + const size_t lensControlsSize = readPOD(m, 0, dataEnd); + m += 4; + dataSize -= 4; + if (dataSize < lensControlsSize) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "lensControls" + << ": not enough data, expected " + << (lensControlsSize) << ", got " << (dataSize); + return ret; + } + if (lensControlsSize > 0) + ret.lensControls = + IPADataSerializer::deserialize(m, m + lensControlsSize, cs); + m += lensControlsSize; + dataSize -= lensControlsSize; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "lsTableHandle" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.lsTableHandle = IPADataSerializer::deserialize(m, m + 4, n, n + 1, cs); + + return ret; + } +}; + +template<> +class IPADataSerializer +{ +public: + static std::tuple, std::vector> + serialize(const ipa::RPi::ConfigResult &data, + ControlSerializer *cs) + { + std::vector retData; + + std::vector modeSensitivity; + std::tie(modeSensitivity, std::ignore) = + IPADataSerializer::serialize(data.modeSensitivity); + retData.insert(retData.end(), modeSensitivity.begin(), modeSensitivity.end()); + + if (data.controlInfo.size() > 0) { + std::vector controlInfo; + std::tie(controlInfo, std::ignore) = + IPADataSerializer::serialize(data.controlInfo, cs); + appendPOD(retData, controlInfo.size()); + retData.insert(retData.end(), controlInfo.begin(), controlInfo.end()); + } else { + appendPOD(retData, 0); + } + + if (data.sensorControls.size() > 0) { + std::vector sensorControls; + std::tie(sensorControls, std::ignore) = + IPADataSerializer::serialize(data.sensorControls, cs); + appendPOD(retData, sensorControls.size()); + retData.insert(retData.end(), sensorControls.begin(), sensorControls.end()); + } else { + appendPOD(retData, 0); + } + + if (data.lensControls.size() > 0) { + std::vector lensControls; + std::tie(lensControls, std::ignore) = + IPADataSerializer::serialize(data.lensControls, cs); + appendPOD(retData, lensControls.size()); + retData.insert(retData.end(), lensControls.begin(), lensControls.end()); + } else { + appendPOD(retData, 0); + } + + return {retData, {}}; + } + + static ipa::RPi::ConfigResult + deserialize(std::vector &data, + ControlSerializer *cs) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), cs); + } + + + static ipa::RPi::ConfigResult + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + ControlSerializer *cs) + { + ipa::RPi::ConfigResult ret; + std::vector::const_iterator m = dataBegin; + + size_t dataSize = std::distance(dataBegin, dataEnd); + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "modeSensitivity" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.modeSensitivity = IPADataSerializer::deserialize(m, m + 4); + m += 4; + dataSize -= 4; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "controlInfoSize" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + const size_t controlInfoSize = readPOD(m, 0, dataEnd); + m += 4; + dataSize -= 4; + if (dataSize < controlInfoSize) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "controlInfo" + << ": not enough data, expected " + << (controlInfoSize) << ", got " << (dataSize); + return ret; + } + if (controlInfoSize > 0) + ret.controlInfo = + IPADataSerializer::deserialize(m, m + controlInfoSize, cs); + m += controlInfoSize; + dataSize -= controlInfoSize; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "sensorControlsSize" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + const size_t sensorControlsSize = readPOD(m, 0, dataEnd); + m += 4; + dataSize -= 4; + if (dataSize < sensorControlsSize) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "sensorControls" + << ": not enough data, expected " + << (sensorControlsSize) << ", got " << (dataSize); + return ret; + } + if (sensorControlsSize > 0) + ret.sensorControls = + IPADataSerializer::deserialize(m, m + sensorControlsSize, cs); + m += sensorControlsSize; + dataSize -= sensorControlsSize; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "lensControlsSize" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + const size_t lensControlsSize = readPOD(m, 0, dataEnd); + m += 4; + dataSize -= 4; + if (dataSize < lensControlsSize) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "lensControls" + << ": not enough data, expected " + << (lensControlsSize) << ", got " << (dataSize); + return ret; + } + if (lensControlsSize > 0) + ret.lensControls = + IPADataSerializer::deserialize(m, m + lensControlsSize, cs); + + return ret; + } + + static ipa::RPi::ConfigResult + deserialize(std::vector &data, + [[maybe_unused]] std::vector &fds, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), cs); + } + + static ipa::RPi::ConfigResult + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + [[maybe_unused]] std::vector::const_iterator fdsBegin, + [[maybe_unused]] std::vector::const_iterator fdsEnd, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(dataBegin, dataEnd, cs); + } +}; + +template<> +class IPADataSerializer +{ +public: + static std::tuple, std::vector> + serialize(const ipa::RPi::StartResult &data, + ControlSerializer *cs) + { + std::vector retData; + + if (data.controls.size() > 0) { + std::vector controls; + std::tie(controls, std::ignore) = + IPADataSerializer::serialize(data.controls, cs); + appendPOD(retData, controls.size()); + retData.insert(retData.end(), controls.begin(), controls.end()); + } else { + appendPOD(retData, 0); + } + + std::vector startupFrameCount; + std::tie(startupFrameCount, std::ignore) = + IPADataSerializer::serialize(data.startupFrameCount); + retData.insert(retData.end(), startupFrameCount.begin(), startupFrameCount.end()); + + std::vector invalidFrameCount; + std::tie(invalidFrameCount, std::ignore) = + IPADataSerializer::serialize(data.invalidFrameCount); + retData.insert(retData.end(), invalidFrameCount.begin(), invalidFrameCount.end()); + + return {retData, {}}; + } + + static ipa::RPi::StartResult + deserialize(std::vector &data, + ControlSerializer *cs) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), cs); + } + + + static ipa::RPi::StartResult + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + ControlSerializer *cs) + { + ipa::RPi::StartResult ret; + std::vector::const_iterator m = dataBegin; + + size_t dataSize = std::distance(dataBegin, dataEnd); + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "controlsSize" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + const size_t controlsSize = readPOD(m, 0, dataEnd); + m += 4; + dataSize -= 4; + if (dataSize < controlsSize) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "controls" + << ": not enough data, expected " + << (controlsSize) << ", got " << (dataSize); + return ret; + } + if (controlsSize > 0) + ret.controls = + IPADataSerializer::deserialize(m, m + controlsSize, cs); + m += controlsSize; + dataSize -= controlsSize; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "startupFrameCount" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.startupFrameCount = IPADataSerializer::deserialize(m, m + 4); + m += 4; + dataSize -= 4; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "invalidFrameCount" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.invalidFrameCount = IPADataSerializer::deserialize(m, m + 4); + + return ret; + } + + static ipa::RPi::StartResult + deserialize(std::vector &data, + [[maybe_unused]] std::vector &fds, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), cs); + } + + static ipa::RPi::StartResult + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + [[maybe_unused]] std::vector::const_iterator fdsBegin, + [[maybe_unused]] std::vector::const_iterator fdsEnd, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(dataBegin, dataEnd, cs); + } +}; + +template<> +class IPADataSerializer +{ +public: + static std::tuple, std::vector> + serialize(const ipa::RPi::PrepareParams &data, + ControlSerializer *cs) + { + std::vector retData; + + std::vector buffers; + std::tie(buffers, std::ignore) = + IPADataSerializer::serialize(data.buffers, cs); + appendPOD(retData, buffers.size()); + retData.insert(retData.end(), buffers.begin(), buffers.end()); + + if (data.sensorControls.size() > 0) { + std::vector sensorControls; + std::tie(sensorControls, std::ignore) = + IPADataSerializer::serialize(data.sensorControls, cs); + appendPOD(retData, sensorControls.size()); + retData.insert(retData.end(), sensorControls.begin(), sensorControls.end()); + } else { + appendPOD(retData, 0); + } + + if (data.requestControls.size() > 0) { + std::vector requestControls; + std::tie(requestControls, std::ignore) = + IPADataSerializer::serialize(data.requestControls, cs); + appendPOD(retData, requestControls.size()); + retData.insert(retData.end(), requestControls.begin(), requestControls.end()); + } else { + appendPOD(retData, 0); + } + + std::vector ipaContext; + std::tie(ipaContext, std::ignore) = + IPADataSerializer::serialize(data.ipaContext); + retData.insert(retData.end(), ipaContext.begin(), ipaContext.end()); + + std::vector delayContext; + std::tie(delayContext, std::ignore) = + IPADataSerializer::serialize(data.delayContext); + retData.insert(retData.end(), delayContext.begin(), delayContext.end()); + + return {retData, {}}; + } + + static ipa::RPi::PrepareParams + deserialize(std::vector &data, + ControlSerializer *cs) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), cs); + } + + + static ipa::RPi::PrepareParams + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + ControlSerializer *cs) + { + ipa::RPi::PrepareParams ret; + std::vector::const_iterator m = dataBegin; + + size_t dataSize = std::distance(dataBegin, dataEnd); + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "buffersSize" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + const size_t buffersSize = readPOD(m, 0, dataEnd); + m += 4; + dataSize -= 4; + if (dataSize < buffersSize) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "buffers" + << ": not enough data, expected " + << (buffersSize) << ", got " << (dataSize); + return ret; + } + ret.buffers = + IPADataSerializer::deserialize(m, m + buffersSize, cs); + m += buffersSize; + dataSize -= buffersSize; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "sensorControlsSize" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + const size_t sensorControlsSize = readPOD(m, 0, dataEnd); + m += 4; + dataSize -= 4; + if (dataSize < sensorControlsSize) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "sensorControls" + << ": not enough data, expected " + << (sensorControlsSize) << ", got " << (dataSize); + return ret; + } + if (sensorControlsSize > 0) + ret.sensorControls = + IPADataSerializer::deserialize(m, m + sensorControlsSize, cs); + m += sensorControlsSize; + dataSize -= sensorControlsSize; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "requestControlsSize" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + const size_t requestControlsSize = readPOD(m, 0, dataEnd); + m += 4; + dataSize -= 4; + if (dataSize < requestControlsSize) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "requestControls" + << ": not enough data, expected " + << (requestControlsSize) << ", got " << (dataSize); + return ret; + } + if (requestControlsSize > 0) + ret.requestControls = + IPADataSerializer::deserialize(m, m + requestControlsSize, cs); + m += requestControlsSize; + dataSize -= requestControlsSize; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "ipaContext" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.ipaContext = IPADataSerializer::deserialize(m, m + 4); + m += 4; + dataSize -= 4; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "delayContext" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.delayContext = IPADataSerializer::deserialize(m, m + 4); + + return ret; + } + + static ipa::RPi::PrepareParams + deserialize(std::vector &data, + [[maybe_unused]] std::vector &fds, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), cs); + } + + static ipa::RPi::PrepareParams + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + [[maybe_unused]] std::vector::const_iterator fdsBegin, + [[maybe_unused]] std::vector::const_iterator fdsEnd, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(dataBegin, dataEnd, cs); + } +}; + +template<> +class IPADataSerializer +{ +public: + static std::tuple, std::vector> + serialize(const ipa::RPi::ProcessParams &data, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + std::vector retData; + + std::vector buffers; + std::tie(buffers, std::ignore) = + IPADataSerializer::serialize(data.buffers, cs); + appendPOD(retData, buffers.size()); + retData.insert(retData.end(), buffers.begin(), buffers.end()); + + std::vector ipaContext; + std::tie(ipaContext, std::ignore) = + IPADataSerializer::serialize(data.ipaContext); + retData.insert(retData.end(), ipaContext.begin(), ipaContext.end()); + + return {retData, {}}; + } + + static ipa::RPi::ProcessParams + deserialize(std::vector &data, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), cs); + } + + + static ipa::RPi::ProcessParams + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + ipa::RPi::ProcessParams ret; + std::vector::const_iterator m = dataBegin; + + size_t dataSize = std::distance(dataBegin, dataEnd); + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "buffersSize" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + const size_t buffersSize = readPOD(m, 0, dataEnd); + m += 4; + dataSize -= 4; + if (dataSize < buffersSize) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "buffers" + << ": not enough data, expected " + << (buffersSize) << ", got " << (dataSize); + return ret; + } + ret.buffers = + IPADataSerializer::deserialize(m, m + buffersSize, cs); + m += buffersSize; + dataSize -= buffersSize; + + + if (dataSize < 4) { + LOG(IPADataSerializer, Error) + << "Failed to deserialize " << "ipaContext" + << ": not enough data, expected " + << (4) << ", got " << (dataSize); + return ret; + } + ret.ipaContext = IPADataSerializer::deserialize(m, m + 4); + + return ret; + } + + static ipa::RPi::ProcessParams + deserialize(std::vector &data, + [[maybe_unused]] std::vector &fds, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(data.cbegin(), data.cend(), cs); + } + + static ipa::RPi::ProcessParams + deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + [[maybe_unused]] std::vector::const_iterator fdsBegin, + [[maybe_unused]] std::vector::const_iterator fdsEnd, + ControlSerializer *cs = nullptr) + { + return IPADataSerializer::deserialize(dataBegin, dataEnd, cs); + } +}; + + +} /* namespace libcamera */ \ No newline at end of file diff --git a/meson_generated/include/libcamera/libcamera.h b/meson_generated/include/libcamera/libcamera.h new file mode 100644 index 00000000..6d85e090 --- /dev/null +++ b/meson_generated/include/libcamera/libcamera.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* This file is auto-generated, do not edit! */ +/* + * Copyright (C) 2018-2019, Google Inc. + * + * libcamera public API + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/meson_generated/include/libcamera/property_ids.h b/meson_generated/include/libcamera/property_ids.h new file mode 100644 index 00000000..fdb72cdc --- /dev/null +++ b/meson_generated/include/libcamera/property_ids.h @@ -0,0 +1,99 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * Properties ID list + * + * This file is auto-generated. Do not edit. + */ + +#pragma once + +#include +#include +#include +#include +#include + +#include + +namespace libcamera { + +namespace properties { + +extern const ControlIdMap properties; + + +enum { + LOCATION = 1, + ROTATION = 2, + MODEL = 3, + UNIT_CELL_SIZE = 4, + PIXEL_ARRAY_SIZE = 5, + PIXEL_ARRAY_OPTICAL_BLACK_RECTANGLES = 6, + PIXEL_ARRAY_ACTIVE_AREAS = 7, + SCALER_CROP_MAXIMUM = 8, + SENSOR_SENSITIVITY = 9, + SYSTEM_DEVICES = 10, + PIPELINE_HANDLER = 11, +}; + + +enum LocationEnum { + CameraLocationFront = 0, + CameraLocationBack = 1, + CameraLocationExternal = 2, +}; +extern const std::array LocationValues; +extern const std::map LocationNameValueMap; +extern const Control Location; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_PROPERTIES_LOCATION +extern const Control Rotation; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_PROPERTIES_ROTATION +extern const Control Model; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_PROPERTIES_MODEL +extern const Control UnitCellSize; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_PROPERTIES_UNIT_CELL_SIZE +extern const Control PixelArraySize; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_PROPERTIES_PIXEL_ARRAY_SIZE +extern const Control> PixelArrayOpticalBlackRectangles; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_PROPERTIES_PIXEL_ARRAY_OPTICAL_BLACK_RECTANGLES +extern const Control> PixelArrayActiveAreas; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_PROPERTIES_PIXEL_ARRAY_ACTIVE_AREAS +extern const Control ScalerCropMaximum; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_PROPERTIES_SCALER_CROP_MAXIMUM +extern const Control SensorSensitivity; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_PROPERTIES_SENSOR_SENSITIVITY +extern const Control> SystemDevices; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_PROPERTIES_SYSTEM_DEVICES +extern const Control PipelineHandler; +#define LIBCAMERA_HAS_LIBCAMERA_VENDOR_PROPERTIES_PIPELINE_HANDLER + +namespace draft { + +#define LIBCAMERA_HAS_DRAFT_VENDOR_PROPERTIES + + +enum { + COLOR_FILTER_ARRANGEMENT = 10001, +}; + + +enum ColorFilterArrangementEnum { + RGGB = 0, + GRBG = 1, + GBRG = 2, + BGGR = 3, + RGB = 4, + MONO = 5, +}; +extern const std::array ColorFilterArrangementValues; +extern const std::map ColorFilterArrangementNameValueMap; +extern const Control ColorFilterArrangement; +#define LIBCAMERA_HAS_DRAFT_VENDOR_PROPERTIES_COLOR_FILTER_ARRANGEMENT + +} /* namespace draft */ + +} /* namespace properties */ + +} /* namespace libcamera */ \ No newline at end of file diff --git a/meson_generated/src/ipa-priv-key.pem b/meson_generated/src/ipa-priv-key.pem new file mode 100644 index 00000000..3116f62c --- /dev/null +++ b/meson_generated/src/ipa-priv-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCyUg1y0NHdUlX+ +aW4IO2dMUrRpi0xorITJp5T0/h7lVjCtnnLWfEUbliGnrmRzBTtdfJpfq4zKBGVr +4uJXOexU3kYPKWShLeTPNIV5xOZLLo4wl0id7wXhUj12GcTQ+ybnwm+/qdd6eBl2 +2aldic9+HMH7CH5l7qX+JAirtFZVR2R+6tG6Hrh9no+jHNEB11n9fQUiBWsiIqSK +UtHpRai/8qsKT+0oGd+3ZFlEi7SCjcfTKNNCPYbXtWUE8DoaYz9KQPYC1s+fU5Ef +0kyr7s7V9s8/AqxpeYICU1Soe3/m/h2N+05RixS5Iac1pP8uaz3Y05IWgT/UbW1H +bqdD2hnFAgMBAAECggEACg0R8PzQN3dinXp310Lx6Z1nyeMuJWBEA9HMVZrVRvv6 +tm6N7oUGqC1oLDlqNAmBdR2G3gmfX+urg89ADsaXCZmVvVkJ8QPTN9KwC1ML4AT5 +wsdkMnK8lBy8liGRtG3TnZCaF+WM3bxTQx21rC4OYf9g97Nc3IX9GTwSuQrrKtdJ +ICDB6LMBK6ef8l0srKgWHVQ6QR04YY/y/8H3uoNoapPBVlli0bRBVcMHN9+FzBuR +wmQQ7CJzMI78mCGd5PR3vw+4P0vm02QSSZU4bKuqUc0BnQ04mUt/CVmrPXT+m5e6 +wfUmpR7SI9wskSEORVF+heaXQeOESKuv+Ga3DavI6QKBgQDBY/i6s9FfCl3d7KlP +OY3Ano3PMKtuw+1XgdAzjaJ4WB2BZi0VOH7xzjUKD9SkzwA4uLPooXiZo8AeVoMQ +wBPOlcNpYLWGAz3TskXiA6a+h4P3kfp7UymDX41ijurrlG5DkcQNy/hM411IAOMV +rOoCK8dy0cMul5tO0RUSiQigAwKBgQDsDRftEMXN+EGxKLiZFFPw3rPq3ZFSzVhU +H1AQZR9QJZGHvtYdcG6BGzIDd1T0AaFjcjRgAs4fB7tClZoRMjqZ5x4ZhbTAuAVE +uoHh3RVELlbinx0lIavdlvFtGfbdL+NELUmk/YCJRx9nkhBDtenAOPWWkpVx1LtX ++fm0lOvolwKBgQCQKIqf+i0HkL26EZGAGiH9xPNm0BvqvKhuw7jExT6oQN71t4nB +uNSAQbut3XEgzaGXpq+NqNgyhytOMiUPVm8tXtxE8C9AT6hF5y1KtngUrQYFhU7X +oX1fjdnh7zFVHNc5DS69Lh/QiOffJbIhVT03ExVhFNZPI/pEvXzczUOdqwKBgQCN +ZkKA1d1HxoDDeNsrh8vIq/8mn9cfvLY+ngs95vVc80Q8BosIU4M+f2X0QZV4HUnp +4k2RfdyvJdh8yFTkHCySaKnVLAzcrN8rDnYjMGY+02tkkV/KEGN9d5/jdPw1/yuq +eV52IQzQLvSW/B4WEXCWnwguTFyNNZuL1chI7jRqvQKBgB00U7LLj1Q91FsdH7ue +jHTcWcWwFLrsjpTFJvB/IfT5ecfbG4GPAfsBLN/9WtxpolE+0gYHHmDz+8Xhgrtc +EMFBaGFB2TojnCL7rcQ8pGccqeTROL/WIz0S/EJ0RTl0Po4OUXYxygQHQEJyRCT5 +M/2F2joV56ADNLqewkwSuQE1 +-----END PRIVATE KEY----- diff --git a/meson_generated/src/libcamera/control_ids.cpp b/meson_generated/src/libcamera/control_ids.cpp new file mode 100644 index 00000000..d6d4264b --- /dev/null +++ b/meson_generated/src/libcamera/control_ids.cpp @@ -0,0 +1,2761 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * controls ID list + * + * This file is auto-generated. Do not edit. + */ + +#include +#include + +/** + * \file control_ids.h + * \brief Camera controls identifiers + */ + +namespace libcamera { + +/** + * \brief Namespace for libcamera controls + */ +namespace controls { + +/** + * \var AeEnable + * \brief Enable or disable the AEGC algorithm. When this control is set to true, + * both ExposureTimeMode and AnalogueGainMode are set to auto, and if this + * control is set to false then both are set to manual. + * + * If ExposureTimeMode or AnalogueGainMode are also set in the same + * request as AeEnable, then the modes supplied by ExposureTimeMode or + * AnalogueGainMode will take precedence. + * + * \sa ExposureTimeMode AnalogueGainMode + */ + +/** + * \enum AeStateEnum + * \brief Supported AeState values + * + * \var AeStateIdle + * \brief The AEGC algorithm is inactive. + * + * This state is returned when both AnalogueGainMode and + * ExposureTimeMode are set to Manual and the algorithm is not + * actively computing any value. + * + * \var AeStateSearching + * \brief The AEGC algorithm is actively computing new values, for either the + * exposure time or the analogue gain, but has not converged to a + * stable result yet. + * + * This state is returned if at least one of AnalogueGainMode or + * ExposureTimeMode is auto and the algorithm hasn't converged yet. + * + * The AEGC algorithm converges once stable values are computed for + * all of the controls set to be computed in Auto mode. Once the + * algorithm converges the state is moved to AeStateConverged. + * + * \var AeStateConverged + * \brief The AEGC algorithm has converged. + * + * This state is returned if at least one of AnalogueGainMode or + * ExposureTimeMode is Auto, and the AEGC algorithm has converged to a + * stable value. + * + * If the measurements move too far away from the convergence point + * then the AEGC algorithm might start adjusting again, in which case + * the state is moved to AeStateSearching. + */ + +/** + * \var AeStateValues + * \brief List of all AeState supported values + */ + +/** + * \var AeStateNameValueMap + * \brief Map of all AeState supported value names (in std::string format) to value + */ + +/** + * \var AeState + * \brief Report the AEGC algorithm state. + * + * The AEGC algorithm computes the exposure time and the analogue gain + * to be applied to the image sensor. + * + * The AEGC algorithm behaviour is controlled by the ExposureTimeMode and + * AnalogueGainMode controls, which allow applications to decide how + * the exposure time and gain are computed, in Auto or Manual mode, + * independently from one another. + * + * The AeState control reports the AEGC algorithm state through a single + * value and describes it as a single computation block which computes + * both the exposure time and the analogue gain values. + * + * When both the exposure time and analogue gain values are configured to + * be in Manual mode, the AEGC algorithm is quiescent and does not actively + * compute any value and the AeState control will report AeStateIdle. + * + * When at least the exposure time or analogue gain are configured to be + * computed by the AEGC algorithm, the AeState control will report if the + * algorithm has converged to stable values for all of the controls set + * to be computed in Auto mode. + * + * \sa AnalogueGainMode + * \sa ExposureTimeMode + */ + +/** + * \enum AeMeteringModeEnum + * \brief Supported AeMeteringMode values + * + * \var MeteringCentreWeighted + * \brief Centre-weighted metering mode. + * + * \var MeteringSpot + * \brief Spot metering mode. + * + * \var MeteringMatrix + * \brief Matrix metering mode. + * + * \var MeteringCustom + * \brief Custom metering mode. + */ + +/** + * \var AeMeteringModeValues + * \brief List of all AeMeteringMode supported values + */ + +/** + * \var AeMeteringModeNameValueMap + * \brief Map of all AeMeteringMode supported value names (in std::string format) to value + */ + +/** + * \var AeMeteringMode + * \brief Specify a metering mode for the AE algorithm to use. + * + * The metering modes determine which parts of the image are used to + * determine the scene brightness. Metering modes may be platform specific + * and not all metering modes may be supported. + */ + +/** + * \enum AeConstraintModeEnum + * \brief Supported AeConstraintMode values + * + * \var ConstraintNormal + * \brief Default constraint mode. + * + * This mode aims to balance the exposure of different parts of the + * image so as to reach a reasonable average level. However, highlights + * in the image may appear over-exposed and lowlights may appear + * under-exposed. + * + * \var ConstraintHighlight + * \brief Highlight constraint mode. + * + * This mode adjusts the exposure levels in order to try and avoid + * over-exposing the brightest parts (highlights) of an image. + * Other non-highlight parts of the image may appear under-exposed. + * + * \var ConstraintShadows + * \brief Shadows constraint mode. + * + * This mode adjusts the exposure levels in order to try and avoid + * under-exposing the dark parts (shadows) of an image. Other normally + * exposed parts of the image may appear over-exposed. + * + * \var ConstraintCustom + * \brief Custom constraint mode. + */ + +/** + * \var AeConstraintModeValues + * \brief List of all AeConstraintMode supported values + */ + +/** + * \var AeConstraintModeNameValueMap + * \brief Map of all AeConstraintMode supported value names (in std::string format) to value + */ + +/** + * \var AeConstraintMode + * \brief Specify a constraint mode for the AE algorithm to use. + * + * The constraint modes determine how the measured scene brightness is + * adjusted to reach the desired target exposure. Constraint modes may be + * platform specific, and not all constraint modes may be supported. + */ + +/** + * \enum AeExposureModeEnum + * \brief Supported AeExposureMode values + * + * \var ExposureNormal + * \brief Default exposure mode. + * + * \var ExposureShort + * \brief Exposure mode allowing only short exposure times. + * + * \var ExposureLong + * \brief Exposure mode allowing long exposure times. + * + * \var ExposureCustom + * \brief Custom exposure mode. + */ + +/** + * \var AeExposureModeValues + * \brief List of all AeExposureMode supported values + */ + +/** + * \var AeExposureModeNameValueMap + * \brief Map of all AeExposureMode supported value names (in std::string format) to value + */ + +/** + * \var AeExposureMode + * \brief Specify an exposure mode for the AE algorithm to use. + * + * The exposure modes specify how the desired total exposure is divided + * between the exposure time and the sensor's analogue gain. They are + * platform specific, and not all exposure modes may be supported. + * + * When one of AnalogueGainMode or ExposureTimeMode is set to Manual, + * the fixed values will override any choices made by AeExposureMode. + * + * \sa AnalogueGainMode + * \sa ExposureTimeMode + */ + +/** + * \var ExposureValue + * \brief Specify an Exposure Value (EV) parameter. + * + * The EV parameter will only be applied if the AE algorithm is currently + * enabled, that is, at least one of AnalogueGainMode and ExposureTimeMode + * are in Auto mode. + * + * By convention EV adjusts the exposure as log2. For example + * EV = [-2, -1, -0.5, 0, 0.5, 1, 2] results in an exposure adjustment + * of [1/4x, 1/2x, 1/sqrt(2)x, 1x, sqrt(2)x, 2x, 4x]. + * + * \sa AnalogueGainMode + * \sa ExposureTimeMode + */ + +/** + * \var ExposureTime + * \brief Exposure time for the frame applied in the sensor device. + * + * This value is specified in microseconds. + * + * This control will only take effect if ExposureTimeMode is Manual. If + * this control is set when ExposureTimeMode is Auto, the value will be + * ignored and will not be retained. + * + * When reported in metadata, this control indicates what exposure time + * was used for the current frame, regardless of ExposureTimeMode. + * ExposureTimeMode will indicate the source of the exposure time value, + * whether it came from the AE algorithm or not. + * + * \sa AnalogueGain + * \sa ExposureTimeMode + */ + +/** + * \enum ExposureTimeModeEnum + * \brief Supported ExposureTimeMode values + * + * \var ExposureTimeModeAuto + * \brief The exposure time will be calculated automatically and set by the + * AE algorithm. + * + * If ExposureTime is set while this mode is active, it will be + * ignored, and its value will not be retained. + * + * When transitioning from Manual to Auto mode, the AEGC should start + * its adjustments based on the last set manual ExposureTime value. + * + * \var ExposureTimeModeManual + * \brief The exposure time will not be updated by the AE algorithm. + * + * When transitioning from Auto to Manual mode, the last computed + * exposure value is used until a new value is specified through the + * ExposureTime control. If an ExposureTime value is specified in the + * same request where the ExposureTimeMode is changed from Auto to + * Manual, the provided ExposureTime is applied immediately. + */ + +/** + * \var ExposureTimeModeValues + * \brief List of all ExposureTimeMode supported values + */ + +/** + * \var ExposureTimeModeNameValueMap + * \brief Map of all ExposureTimeMode supported value names (in std::string format) to value + */ + +/** + * \var ExposureTimeMode + * \brief Controls the source of the exposure time that is applied to the image + * sensor. + * + * When set to Auto, the AE algorithm computes the exposure time and + * configures the image sensor accordingly. When set to Manual, the value + * of the ExposureTime control is used. + * + * When transitioning from Auto to Manual mode and no ExposureTime control + * is provided by the application, the last value computed by the AE + * algorithm when the mode was Auto will be used. If the ExposureTimeMode + * was never set to Auto (either because the camera started in Manual mode, + * or Auto is not supported by the camera), the camera should use a + * best-effort default value. + * + * If ExposureTimeModeManual is supported, the ExposureTime control must + * also be supported. + * + * Cameras that support manual control of the sensor shall support manual + * mode for both ExposureTimeMode and AnalogueGainMode, and shall expose + * the ExposureTime and AnalogueGain controls. If the camera also has an + * AEGC implementation, both ExposureTimeMode and AnalogueGainMode shall + * support both manual and auto mode. If auto mode is available, it shall + * be the default mode. These rules do not apply to black box cameras + * such as UVC cameras, where the available gain and exposure modes are + * completely dependent on what the device exposes. + * + * \par Flickerless exposure mode transitions + * + * Applications that wish to transition from ExposureTimeModeAuto to direct + * control of the exposure time without causing extra flicker can do so by + * selecting an ExposureTime value as close as possible to the last value + * computed by the auto exposure algorithm in order to avoid any visible + * flickering. + * + * To select the correct value to use as ExposureTime value, applications + * should accommodate the natural delay in applying controls caused by the + * capture pipeline frame depth. + * + * When switching to manual exposure mode, applications should not + * immediately specify an ExposureTime value in the same request where + * ExposureTimeMode is set to Manual. They should instead wait for the + * first Request where ExposureTimeMode is reported as + * ExposureTimeModeManual in the Request metadata, and use the reported + * ExposureTime to populate the control value in the next Request to be + * queued to the Camera. + * + * The implementation of the auto-exposure algorithm should equally try to + * minimize flickering and when transitioning from manual exposure mode to + * auto exposure use the last value provided by the application as starting + * point. + * + * 1. Start with ExposureTimeMode set to Auto + * + * 2. Set ExposureTimeMode to Manual + * + * 3. Wait for the first completed request that has ExposureTimeMode + * set to Manual + * + * 4. Copy the value reported in ExposureTime into a new request, and + * submit it + * + * 5. Proceed to run manual exposure time as desired + * + * \sa ExposureTime + */ + +/** + * \var AnalogueGain + * \brief Analogue gain value applied in the sensor device. + * + * The value of the control specifies the gain multiplier applied to all + * colour channels. This value cannot be lower than 1.0. + * + * This control will only take effect if AnalogueGainMode is Manual. If + * this control is set when AnalogueGainMode is Auto, the value will be + * ignored and will not be retained. + * + * When reported in metadata, this control indicates what analogue gain + * was used for the current request, regardless of AnalogueGainMode. + * AnalogueGainMode will indicate the source of the analogue gain value, + * whether it came from the AEGC algorithm or not. + * + * \sa ExposureTime + * \sa AnalogueGainMode + */ + +/** + * \enum AnalogueGainModeEnum + * \brief Supported AnalogueGainMode values + * + * \var AnalogueGainModeAuto + * \brief The analogue gain will be calculated automatically and set by the + * AEGC algorithm. + * + * If AnalogueGain is set while this mode is active, it will be + * ignored, and it will also not be retained. + * + * When transitioning from Manual to Auto mode, the AEGC should start + * its adjustments based on the last set manual AnalogueGain value. + * + * \var AnalogueGainModeManual + * \brief The analogue gain will not be updated by the AEGC algorithm. + * + * When transitioning from Auto to Manual mode, the last computed + * gain value is used until a new value is specified through the + * AnalogueGain control. If an AnalogueGain value is specified in the + * same request where the AnalogueGainMode is changed from Auto to + * Manual, the provided AnalogueGain is applied immediately. + */ + +/** + * \var AnalogueGainModeValues + * \brief List of all AnalogueGainMode supported values + */ + +/** + * \var AnalogueGainModeNameValueMap + * \brief Map of all AnalogueGainMode supported value names (in std::string format) to value + */ + +/** + * \var AnalogueGainMode + * \brief Controls the source of the analogue gain that is applied to the image + * sensor. + * + * When set to Auto, the AEGC algorithm computes the analogue gain and + * configures the image sensor accordingly. When set to Manual, the value + * of the AnalogueGain control is used. + * + * When transitioning from Auto to Manual mode and no AnalogueGain control + * is provided by the application, the last value computed by the AEGC + * algorithm when the mode was Auto will be used. If the AnalogueGainMode + * was never set to Auto (either because the camera started in Manual mode, + * or Auto is not supported by the camera), the camera should use a + * best-effort default value. + * + * If AnalogueGainModeManual is supported, the AnalogueGain control must + * also be supported. + * + * For cameras where we have control over the ISP, both ExposureTimeMode + * and AnalogueGainMode are expected to support manual mode, and both + * controls (as well as ExposureTimeMode and AnalogueGain) are expected to + * be present. If the camera also has an AEGC implementation, both + * ExposureTimeMode and AnalogueGainMode shall support both manual and + * auto mode. If auto mode is available, it shall be the default mode. + * These rules do not apply to black box cameras such as UVC cameras, + * where the available gain and exposure modes are completely dependent on + * what the hardware exposes. + * + * The same procedure described for performing flickerless transitions in + * the ExposureTimeMode control documentation can be applied to analogue + * gain. + * + * \sa ExposureTimeMode + * \sa AnalogueGain + */ + +/** + * \enum AeFlickerModeEnum + * \brief Supported AeFlickerMode values + * + * \var FlickerOff + * \brief No flicker avoidance is performed. + * + * \var FlickerManual + * \brief Manual flicker avoidance. + * + * Suppress flicker effects caused by lighting running with a period + * specified by the AeFlickerPeriod control. + * \sa AeFlickerPeriod + * + * \var FlickerAuto + * \brief Automatic flicker period detection and avoidance. + * + * The system will automatically determine the most likely value of + * flicker period, and avoid flicker of this frequency. Once flicker + * is being corrected, it is implementation dependent whether the + * system is still able to detect a change in the flicker period. + * \sa AeFlickerDetected + */ + +/** + * \var AeFlickerModeValues + * \brief List of all AeFlickerMode supported values + */ + +/** + * \var AeFlickerModeNameValueMap + * \brief Map of all AeFlickerMode supported value names (in std::string format) to value + */ + +/** + * \var AeFlickerMode + * \brief Set the flicker avoidance mode for AGC/AEC. + * + * The flicker mode determines whether, and how, the AGC/AEC algorithm + * attempts to hide flicker effects caused by the duty cycle of artificial + * lighting. + * + * Although implementation dependent, many algorithms for "flicker + * avoidance" work by restricting this exposure time to integer multiples + * of the cycle period, wherever possible. + * + * Implementations may not support all of the flicker modes listed below. + * + * By default the system will start in FlickerAuto mode if this is + * supported, otherwise the flicker mode will be set to FlickerOff. + */ + +/** + * \var AeFlickerPeriod + * \brief Manual flicker period in microseconds. + * + * This value sets the current flicker period to avoid. It is used when + * AeFlickerMode is set to FlickerManual. + * + * To cancel 50Hz mains flicker, this should be set to 10000 (corresponding + * to 100Hz), or 8333 (120Hz) for 60Hz mains. + * + * Setting the mode to FlickerManual when no AeFlickerPeriod has ever been + * set means that no flicker cancellation occurs (until the value of this + * control is updated). + * + * Switching to modes other than FlickerManual has no effect on the + * value of the AeFlickerPeriod control. + * + * \sa AeFlickerMode + */ + +/** + * \var AeFlickerDetected + * \brief Flicker period detected in microseconds. + * + * The value reported here indicates the currently detected flicker + * period, or zero if no flicker at all is detected. + * + * When AeFlickerMode is set to FlickerAuto, there may be a period during + * which the value reported here remains zero. Once a non-zero value is + * reported, then this is the flicker period that has been detected and is + * now being cancelled. + * + * In the case of 50Hz mains flicker, the value would be 10000 + * (corresponding to 100Hz), or 8333 (120Hz) for 60Hz mains flicker. + * + * It is implementation dependent whether the system can continue to detect + * flicker of different periods when another frequency is already being + * cancelled. + * + * \sa AeFlickerMode + */ + +/** + * \var Brightness + * \brief Specify a fixed brightness parameter. + * + * Positive values (up to 1.0) produce brighter images; negative values + * (up to -1.0) produce darker images and 0.0 leaves pixels unchanged. + */ + +/** + * \var Contrast + * \brief Specify a fixed contrast parameter. + * + * Normal contrast is given by the value 1.0; larger values produce images + * with more contrast. + */ + +/** + * \var Lux + * \brief Report an estimate of the current illuminance level in lux. + * + * The Lux control can only be returned in metadata. + */ + +/** + * \var AwbEnable + * \brief Enable or disable the AWB. + * + * When AWB is enabled, the algorithm estimates the colour temperature of + * the scene and computes colour gains and the colour correction matrix + * automatically. The computed colour temperature, gains and correction + * matrix are reported in metadata. The corresponding controls are ignored + * if set in a request. + * + * When AWB is disabled, the colour temperature, gains and correction + * matrix are not updated automatically and can be set manually in + * requests. + * + * \sa ColourCorrectionMatrix + * \sa ColourGains + * \sa ColourTemperature + */ + +/** + * \enum AwbModeEnum + * \brief Supported AwbMode values + * + * \var AwbAuto + * \brief Search over the whole colour temperature range. + * + * \var AwbIncandescent + * \brief Incandescent AWB lamp mode. + * + * \var AwbTungsten + * \brief Tungsten AWB lamp mode. + * + * \var AwbFluorescent + * \brief Fluorescent AWB lamp mode. + * + * \var AwbIndoor + * \brief Indoor AWB lighting mode. + * + * \var AwbDaylight + * \brief Daylight AWB lighting mode. + * + * \var AwbCloudy + * \brief Cloudy AWB lighting mode. + * + * \var AwbCustom + * \brief Custom AWB mode. + */ + +/** + * \var AwbModeValues + * \brief List of all AwbMode supported values + */ + +/** + * \var AwbModeNameValueMap + * \brief Map of all AwbMode supported value names (in std::string format) to value + */ + +/** + * \var AwbMode + * \brief Specify the range of illuminants to use for the AWB algorithm. + * + * The modes supported are platform specific, and not all modes may be + * supported. + */ + +/** + * \var AwbLocked + * \brief Report the lock status of a running AWB algorithm. + * + * If the AWB algorithm is locked the value shall be set to true, if it's + * converging it shall be set to false. If the AWB algorithm is not + * running the control shall not be present in the metadata control list. + * + * \sa AwbEnable + */ + +/** + * \var ColourGains + * \brief Pair of gain values for the Red and Blue colour channels, in that + * order. + * + * ColourGains can only be applied in a Request when the AWB is disabled. + * If ColourGains is set in a request but ColourTemperature is not, the + * implementation shall calculate and set the ColourTemperature based on + * the ColourGains. + * + * \sa AwbEnable + * \sa ColourTemperature + */ + +/** + * \var ColourTemperature + * \brief ColourTemperature of the frame, in kelvin. + * + * ColourTemperature can only be applied in a Request when the AWB is + * disabled. + * + * If ColourTemperature is set in a request but ColourGains is not, the + * implementation shall calculate and set the ColourGains based on the + * given ColourTemperature. If ColourTemperature is set (either directly, + * or indirectly by setting ColourGains) but ColourCorrectionMatrix is not, + * the ColourCorrectionMatrix is updated based on the ColourTemperature. + * + * The ColourTemperature used to process the frame is reported in metadata. + * + * \sa AwbEnable + * \sa ColourCorrectionMatrix + * \sa ColourGains + */ + +/** + * \var Saturation + * \brief Specify a fixed saturation parameter. + * + * Normal saturation is given by the value 1.0; larger values produce more + * saturated colours; 0.0 produces a greyscale image. + */ + +/** + * \var SensorBlackLevels + * \brief Reports the sensor black levels used for processing a frame. + * + * The values are in the order R, Gr, Gb, B. They are returned as numbers + * out of a 16-bit pixel range (as if pixels ranged from 0 to 65535). The + * SensorBlackLevels control can only be returned in metadata. + */ + +/** + * \var Sharpness + * \brief Intensity of the sharpening applied to the image. + * + * A value of 0.0 means no sharpening. The minimum value means + * minimal sharpening, and shall be 0.0 unless the camera can't + * disable sharpening completely. The default value shall give a + * "reasonable" level of sharpening, suitable for most use cases. + * The maximum value may apply extremely high levels of sharpening, + * higher than anyone could reasonably want. Negative values are + * not allowed. Note also that sharpening is not applied to raw + * streams. + */ + +/** + * \var FocusFoM + * \brief Reports a Figure of Merit (FoM) to indicate how in-focus the frame is. + * + * A larger FocusFoM value indicates a more in-focus frame. This singular + * value may be based on a combination of statistics gathered from + * multiple focus regions within an image. The number of focus regions and + * method of combination is platform dependent. In this respect, it is not + * necessarily aimed at providing a way to implement a focus algorithm by + * the application, rather an indication of how in-focus a frame is. + */ + +/** + * \var ColourCorrectionMatrix + * \brief The 3x3 matrix that converts camera RGB to sRGB within the imaging + * pipeline. + * + * This should describe the matrix that is used after pixels have been + * white-balanced, but before any gamma transformation. The 3x3 matrix is + * stored in conventional reading order in an array of 9 floating point + * values. + * + * ColourCorrectionMatrix can only be applied in a Request when the AWB is + * disabled. + * + * \sa AwbEnable + * \sa ColourTemperature + */ + +/** + * \var ScalerCrop + * \brief Sets the image portion that will be scaled to form the whole of + * the final output image. + * + * The (x,y) location of this rectangle is relative to the + * PixelArrayActiveAreas that is being used. The units remain native + * sensor pixels, even if the sensor is being used in a binning or + * skipping mode. + * + * This control is only present when the pipeline supports scaling. Its + * maximum valid value is given by the properties::ScalerCropMaximum + * property, and the two can be used to implement digital zoom. + */ + +/** + * \var DigitalGain + * \brief Digital gain value applied during the processing steps applied + * to the image as captured from the sensor. + * + * The global digital gain factor is applied to all the colour channels + * of the RAW image. Different pipeline models are free to + * specify how the global gain factor applies to each separate + * channel. + * + * If an imaging pipeline applies digital gain in distinct + * processing steps, this value indicates their total sum. + * Pipelines are free to decide how to adjust each processing + * step to respect the received gain factor and shall report + * their total value in the request metadata. + */ + +/** + * \var FrameDuration + * \brief The instantaneous frame duration from start of frame exposure to start + * of next exposure, expressed in microseconds. + * + * This control is meant to be returned in metadata. + */ + +/** + * \var FrameDurationLimits + * \brief The minimum and maximum (in that order) frame duration, expressed in + * microseconds. + * + * When provided by applications, the control specifies the sensor frame + * duration interval the pipeline has to use. This limits the largest + * exposure time the sensor can use. For example, if a maximum frame + * duration of 33ms is requested (corresponding to 30 frames per second), + * the sensor will not be able to raise the exposure time above 33ms. + * A fixed frame duration is achieved by setting the minimum and maximum + * values to be the same. Setting both values to 0 reverts to using the + * camera defaults. + * + * The maximum frame duration provides the absolute limit to the exposure + * time computed by the AE algorithm and it overrides any exposure mode + * setting specified with controls::AeExposureMode. Similarly, when a + * manual exposure time is set through controls::ExposureTime, it also + * gets clipped to the limits set by this control. When reported in + * metadata, the control expresses the minimum and maximum frame durations + * used after being clipped to the sensor provided frame duration limits. + * + * \sa AeExposureMode + * \sa ExposureTime + * + * \todo Define how to calculate the capture frame rate by + * defining controls to report additional delays introduced by + * the capture pipeline or post-processing stages (ie JPEG + * conversion, frame scaling). + * + * \todo Provide an explicit definition of default control values, for + * this and all other controls. + */ + +/** + * \var SensorTemperature + * \brief Temperature measure from the camera sensor in Celsius. + * + * This value is typically obtained by a thermal sensor present on-die or + * in the camera module. The range of reported temperatures is device + * dependent. + * + * The SensorTemperature control will only be returned in metadata if a + * thermal sensor is present. + */ + +/** + * \var SensorTimestamp + * \brief The time when the first row of the image sensor active array is exposed. + * + * The timestamp, expressed in nanoseconds, represents a monotonically + * increasing counter since the system boot time, as defined by the + * Linux-specific CLOCK_BOOTTIME clock id. + * + * The SensorTimestamp control can only be returned in metadata. + * + * \todo Define how the sensor timestamp has to be used in the reprocessing + * use case. + */ + +/** + * \enum AfModeEnum + * \brief Supported AfMode values + * + * \var AfModeManual + * \brief The AF algorithm is in manual mode. + * + * In this mode it will never perform any action nor move the lens of + * its own accord, but an application can specify the desired lens + * position using the LensPosition control. The AfState will always + * report AfStateIdle. + * + * If the camera is started in AfModeManual, it will move the focus + * lens to the position specified by the LensPosition control. + * + * This mode is the recommended default value for the AfMode control. + * External cameras (as reported by the Location property set to + * CameraLocationExternal) may use a different default value. + * + * \var AfModeAuto + * \brief The AF algorithm is in auto mode. + * + * In this mode the algorithm will never move the lens or change state + * unless the AfTrigger control is used. The AfTrigger control can be + * used to initiate a focus scan, the results of which will be + * reported by AfState. + * + * If the autofocus algorithm is moved from AfModeAuto to another mode + * while a scan is in progress, the scan is cancelled immediately, + * without waiting for the scan to finish. + * + * When first entering this mode the AfState will report AfStateIdle. + * When a trigger control is sent, AfState will report AfStateScanning + * for a period before spontaneously changing to AfStateFocused or + * AfStateFailed, depending on the outcome of the scan. It will remain + * in this state until another scan is initiated by the AfTrigger + * control. If a scan is cancelled (without changing to another mode), + * AfState will return to AfStateIdle. + * + * \var AfModeContinuous + * \brief The AF algorithm is in continuous mode. + * + * In this mode the lens can re-start a scan spontaneously at any + * moment, without any user intervention. The AfState still reports + * whether the algorithm is currently scanning or not, though the + * application has no ability to initiate or cancel scans, nor to move + * the lens for itself. + * + * However, applications can pause the AF algorithm from continuously + * scanning by using the AfPause control. This allows video or still + * images to be captured whilst guaranteeing that the focus is fixed. + * + * When set to AfModeContinuous, the system will immediately initiate a + * scan so AfState will report AfStateScanning, and will settle on one + * of AfStateFocused or AfStateFailed, depending on the scan result. + */ + +/** + * \var AfModeValues + * \brief List of all AfMode supported values + */ + +/** + * \var AfModeNameValueMap + * \brief Map of all AfMode supported value names (in std::string format) to value + */ + +/** + * \var AfMode + * \brief The mode of the AF (autofocus) algorithm. + * + * An implementation may choose not to implement all the modes. + */ + +/** + * \enum AfRangeEnum + * \brief Supported AfRange values + * + * \var AfRangeNormal + * \brief A wide range of focus distances is scanned. + * + * Scanned distances cover all the way from infinity down to close + * distances, though depending on the implementation, possibly not + * including the very closest macro positions. + * + * \var AfRangeMacro + * \brief Only close distances are scanned. + * + * \var AfRangeFull + * \brief The full range of focus distances is scanned. + * + * This range is similar to AfRangeNormal but includes the very + * closest macro positions. + */ + +/** + * \var AfRangeValues + * \brief List of all AfRange supported values + */ + +/** + * \var AfRangeNameValueMap + * \brief Map of all AfRange supported value names (in std::string format) to value + */ + +/** + * \var AfRange + * \brief The range of focus distances that is scanned. + * + * An implementation may choose not to implement all the options here. + */ + +/** + * \enum AfSpeedEnum + * \brief Supported AfSpeed values + * + * \var AfSpeedNormal + * \brief Move the lens at its usual speed. + * + * \var AfSpeedFast + * \brief Move the lens more quickly. + */ + +/** + * \var AfSpeedValues + * \brief List of all AfSpeed supported values + */ + +/** + * \var AfSpeedNameValueMap + * \brief Map of all AfSpeed supported value names (in std::string format) to value + */ + +/** + * \var AfSpeed + * \brief Determine whether the AF is to move the lens as quickly as possible or + * more steadily. + * + * For example, during video recording it may be desirable not to move the + * lens too abruptly, but when in a preview mode (waiting for a still + * capture) it may be helpful to move the lens as quickly as is reasonably + * possible. + */ + +/** + * \enum AfMeteringEnum + * \brief Supported AfMetering values + * + * \var AfMeteringAuto + * \brief Let the AF algorithm decide for itself where it will measure focus. + * + * \var AfMeteringWindows + * \brief Use the rectangles defined by the AfWindows control to measure focus. + * + * If no windows are specified the behaviour is platform dependent. + */ + +/** + * \var AfMeteringValues + * \brief List of all AfMetering supported values + */ + +/** + * \var AfMeteringNameValueMap + * \brief Map of all AfMetering supported value names (in std::string format) to value + */ + +/** + * \var AfMetering + * \brief The parts of the image used by the AF algorithm to measure focus. + */ + +/** + * \var AfWindows + * \brief The focus windows used by the AF algorithm when AfMetering is set to + * AfMeteringWindows. + * + * The units used are pixels within the rectangle returned by the + * ScalerCropMaximum property. + * + * In order to be activated, a rectangle must be programmed with non-zero + * width and height. Internally, these rectangles are intersected with the + * ScalerCropMaximum rectangle. If the window becomes empty after this + * operation, then the window is ignored. If all the windows end up being + * ignored, then the behaviour is platform dependent. + * + * On platforms that support the ScalerCrop control (for implementing + * digital zoom, for example), no automatic recalculation or adjustment of + * AF windows is performed internally if the ScalerCrop is changed. If any + * window lies outside the output image after the scaler crop has been + * applied, it is up to the application to recalculate them. + * + * The details of how the windows are used are platform dependent. We note + * that when there is more than one AF window, a typical implementation + * might find the optimal focus position for each one and finally select + * the window where the focal distance for the objects shown in that part + * of the image are closest to the camera. + */ + +/** + * \enum AfTriggerEnum + * \brief Supported AfTrigger values + * + * \var AfTriggerStart + * \brief Start an AF scan. + * + * Setting the control to AfTriggerStart is ignored if a scan is in + * progress. + * + * \var AfTriggerCancel + * \brief Cancel an AF scan. + * + * This does not cause the lens to move anywhere else. Ignored if no + * scan is in progress. + */ + +/** + * \var AfTriggerValues + * \brief List of all AfTrigger supported values + */ + +/** + * \var AfTriggerNameValueMap + * \brief Map of all AfTrigger supported value names (in std::string format) to value + */ + +/** + * \var AfTrigger + * \brief Start an autofocus scan. + * + * This control starts an autofocus scan when AfMode is set to AfModeAuto, + * and is ignored if AfMode is set to AfModeManual or AfModeContinuous. It + * can also be used to terminate a scan early. + */ + +/** + * \enum AfPauseEnum + * \brief Supported AfPause values + * + * \var AfPauseImmediate + * \brief Pause the continuous autofocus algorithm immediately. + * + * The autofocus algorithm is paused whether or not any kind of scan + * is underway. AfPauseState will subsequently report + * AfPauseStatePaused. AfState may report any of AfStateScanning, + * AfStateFocused or AfStateFailed, depending on the algorithm's state + * when it received this control. + * + * \var AfPauseDeferred + * \brief Pause the continuous autofocus algorithm at the end of the scan. + * + * This is similar to AfPauseImmediate, and if the AfState is + * currently reporting AfStateFocused or AfStateFailed it will remain + * in that state and AfPauseState will report AfPauseStatePaused. + * + * However, if the algorithm is scanning (AfStateScanning), + * AfPauseState will report AfPauseStatePausing until the scan is + * finished, at which point AfState will report one of AfStateFocused + * or AfStateFailed, and AfPauseState will change to + * AfPauseStatePaused. + * + * \var AfPauseResume + * \brief Resume continuous autofocus operation. + * + * The algorithm starts again from exactly where it left off, and + * AfPauseState will report AfPauseStateRunning. + */ + +/** + * \var AfPauseValues + * \brief List of all AfPause supported values + */ + +/** + * \var AfPauseNameValueMap + * \brief Map of all AfPause supported value names (in std::string format) to value + */ + +/** + * \var AfPause + * \brief Pause lens movements when in continuous autofocus mode. + * + * This control has no effect except when in continuous autofocus mode + * (AfModeContinuous). It can be used to pause any lens movements while + * (for example) images are captured. The algorithm remains inactive + * until it is instructed to resume. + */ + +/** + * \var LensPosition + * \brief Set and report the focus lens position. + * + * This control instructs the lens to move to a particular position and + * also reports back the position of the lens for each frame. + * + * The LensPosition control is ignored unless the AfMode is set to + * AfModeManual, though the value is reported back unconditionally in all + * modes. + * + * This value, which is generally a non-integer, is the reciprocal of the + * focal distance in metres, also known as dioptres. That is, to set a + * focal distance D, the lens position LP is given by + * + * \f$LP = \frac{1\mathrm{m}}{D}\f$ + * + * For example: + * + * - 0 moves the lens to infinity. + * - 0.5 moves the lens to focus on objects 2m away. + * - 2 moves the lens to focus on objects 50cm away. + * - And larger values will focus the lens closer. + * + * The default value of the control should indicate a good general + * position for the lens, often corresponding to the hyperfocal distance + * (the closest position for which objects at infinity are still + * acceptably sharp). The minimum will often be zero (meaning infinity), + * and the maximum value defines the closest focus position. + * + * \todo Define a property to report the Hyperfocal distance of calibrated + * lenses. + */ + +/** + * \enum AfStateEnum + * \brief Supported AfState values + * + * \var AfStateIdle + * \brief The AF algorithm is in manual mode (AfModeManual) or in auto mode + * (AfModeAuto) and a scan has not yet been triggered, or an + * in-progress scan was cancelled. + * + * \var AfStateScanning + * \brief The AF algorithm is in auto mode (AfModeAuto), and a scan has been + * started using the AfTrigger control. + * + * The scan can be cancelled by sending AfTriggerCancel at which point + * the algorithm will either move back to AfStateIdle or, if the scan + * actually completes before the cancel request is processed, to one + * of AfStateFocused or AfStateFailed. + * + * Alternatively the AF algorithm could be in continuous mode + * (AfModeContinuous) at which point it may enter this state + * spontaneously whenever it determines that a rescan is needed. + * + * \var AfStateFocused + * \brief The AF algorithm is in auto (AfModeAuto) or continuous + * (AfModeContinuous) mode and a scan has completed with the result + * that the algorithm believes the image is now in focus. + * + * \var AfStateFailed + * \brief The AF algorithm is in auto (AfModeAuto) or continuous + * (AfModeContinuous) mode and a scan has completed with the result + * that the algorithm did not find a good focus position. + */ + +/** + * \var AfStateValues + * \brief List of all AfState supported values + */ + +/** + * \var AfStateNameValueMap + * \brief Map of all AfState supported value names (in std::string format) to value + */ + +/** + * \var AfState + * \brief The current state of the AF algorithm. + * + * This control reports the current state of the AF algorithm in + * conjunction with the reported AfMode value and (in continuous AF mode) + * the AfPauseState value. The possible state changes are described below, + * though we note the following state transitions that occur when the + * AfMode is changed. + * + * If the AfMode is set to AfModeManual, then the AfState will always + * report AfStateIdle (even if the lens is subsequently moved). Changing + * to the AfModeManual state does not initiate any lens movement. + * + * If the AfMode is set to AfModeAuto then the AfState will report + * AfStateIdle. However, if AfModeAuto and AfTriggerStart are sent + * together then AfState will omit AfStateIdle and move straight to + * AfStateScanning (and start a scan). + * + * If the AfMode is set to AfModeContinuous then the AfState will + * initially report AfStateScanning. + */ + +/** + * \enum AfPauseStateEnum + * \brief Supported AfPauseState values + * + * \var AfPauseStateRunning + * \brief Continuous AF is running and the algorithm may restart a scan + * spontaneously. + * + * \var AfPauseStatePausing + * \brief Continuous AF has been sent an AfPauseDeferred control, and will + * pause as soon as any in-progress scan completes. + * + * When the scan completes, the AfPauseState control will report + * AfPauseStatePaused. No new scans will be start spontaneously until + * the AfPauseResume control is sent. + * + * \var AfPauseStatePaused + * \brief Continuous AF is paused. + * + * No further state changes or lens movements will occur until the + * AfPauseResume control is sent. + */ + +/** + * \var AfPauseStateValues + * \brief List of all AfPauseState supported values + */ + +/** + * \var AfPauseStateNameValueMap + * \brief Map of all AfPauseState supported value names (in std::string format) to value + */ + +/** + * \var AfPauseState + * \brief Report whether the autofocus is currently running, paused or pausing. + * + * This control is only applicable in continuous (AfModeContinuous) mode, + * and reports whether the algorithm is currently running, paused or + * pausing (that is, will pause as soon as any in-progress scan + * completes). + * + * Any change to AfMode will cause AfPauseStateRunning to be reported. + */ + +/** + * \enum HdrModeEnum + * \brief Supported HdrMode values + * + * \var HdrModeOff + * \brief HDR is disabled. + * + * Metadata for this frame will not include the HdrChannel control. + * + * \var HdrModeMultiExposureUnmerged + * \brief Multiple exposures will be generated in an alternating fashion. + * + * The multiple exposures will not be merged together and will be + * returned to the application as they are. Each image will be tagged + * with the correct HDR channel, indicating what kind of exposure it + * is. The tag should be the same as in the HdrModeMultiExposure case. + * + * The expectation is that an application using this mode would merge + * the frames to create HDR images for itself if it requires them. + * + * \var HdrModeMultiExposure + * \brief Multiple exposures will be generated and merged to create HDR + * images. + * + * Each image will be tagged with the HDR channel (long, medium or + * short) that arrived and which caused this image to be output. + * + * Systems that use two channels for HDR will return images tagged + * alternately as the short and long channel. Systems that use three + * channels for HDR will cycle through the short, medium and long + * channel before repeating. + * + * \var HdrModeSingleExposure + * \brief Multiple frames all at a single exposure will be used to create HDR + * images. + * + * These images should be reported as all corresponding to the HDR + * short channel. + * + * \var HdrModeNight + * \brief Multiple frames will be combined to produce "night mode" images. + * + * It is up to the implementation exactly which HDR channels it uses, + * and the images will all be tagged accordingly with the correct HDR + * channel information. + */ + +/** + * \var HdrModeValues + * \brief List of all HdrMode supported values + */ + +/** + * \var HdrModeNameValueMap + * \brief Map of all HdrMode supported value names (in std::string format) to value + */ + +/** + * \var HdrMode + * \brief Set the mode to be used for High Dynamic Range (HDR) imaging. + * + * HDR techniques typically include multiple exposure, image fusion and + * tone mapping techniques to improve the dynamic range of the resulting + * images. + * + * When using an HDR mode, images are captured with different sets of AGC + * settings called HDR channels. Channels indicate in particular the type + * of exposure (short, medium or long) used to capture the raw image, + * before fusion. Each HDR image is tagged with the corresponding channel + * using the HdrChannel control. + * + * \sa HdrChannel + */ + +/** + * \enum HdrChannelEnum + * \brief Supported HdrChannel values + * + * \var HdrChannelNone + * \brief This image does not correspond to any of the captures used to create + * an HDR image. + * + * \var HdrChannelShort + * \brief This is a short exposure image. + * + * \var HdrChannelMedium + * \brief This is a medium exposure image. + * + * \var HdrChannelLong + * \brief This is a long exposure image. + */ + +/** + * \var HdrChannelValues + * \brief List of all HdrChannel supported values + */ + +/** + * \var HdrChannelNameValueMap + * \brief Map of all HdrChannel supported value names (in std::string format) to value + */ + +/** + * \var HdrChannel + * \brief The HDR channel used to capture the frame. + * + * This value is reported back to the application so that it can discover + * whether this capture corresponds to the short or long exposure image + * (or any other image used by the HDR procedure). An application can + * monitor the HDR channel to discover when the differently exposed images + * have arrived. + * + * This metadata is only available when an HDR mode has been enabled. + * + * \sa HdrMode + */ + +/** + * \var Gamma + * \brief Specify a fixed gamma value. + * + * The default gamma value must be 2.2 which closely mimics sRGB gamma. + * Note that this is camera gamma, so it is applied as 1.0/gamma. + */ + +/** + * \var DebugMetadataEnable + * \brief Enable or disable the debug metadata. + */ + +/** + * \var FrameWallClock + * \brief This timestamp corresponds to the same moment in time as the + * SensorTimestamp, but is represented as a wall clock time as measured by + * the CLOCK_REALTIME clock. Like SensorTimestamp, the timestamp value is + * expressed in nanoseconds. + * + * Being a wall clock measurement, it can be used to synchronise timing + * across different devices. + * + * \sa SensorTimestamp + * + * The FrameWallClock control can only be returned in metadata. + */ + +/** + * \enum WdrModeEnum + * \brief Supported WdrMode values + * + * \var WdrOff + * \brief Wdr is disabled. + * + * \var WdrLinear + * \brief Apply a linear global tone mapping curve. + * A curve with two linear sections is applied. This produces good results at the expense of a slightly artificial look. + * + * \var WdrPower + * \brief Apply a power global tone mapping curve. + * + * This curve has high gain values on the dark areas of an image and + * high compression values on the bright area. It therefore tends to + * produce noticeable noise artifacts. + * + * \var WdrExponential + * \brief Apply an exponential global tone mapping curve. + * + * This curve has lower gain values in dark areas compared to the power + * curve but produces a more natural look compared to the linear curve. + * It is therefore the best choice for most scenes. + * + * \var WdrHistogramEqualization + * \brief Apply histogram equalization. + * + * This curve preserves most of the information of the image at the + * expense of a very artificial look. It is therefore best suited for + * technical analysis. + */ + +/** + * \var WdrModeValues + * \brief List of all WdrMode supported values + */ + +/** + * \var WdrModeNameValueMap + * \brief Map of all WdrMode supported value names (in std::string format) to value + */ + +/** + * \var WdrMode + * \brief Set the WDR mode. + * + * The WDR mode is used to select the algorithm used for global tone + * mapping. It will automatically reduce the exposure time of the sensor + * so that there are only a small number of saturated pixels in the image. + * The algorithm then compensates for the loss of brightness by applying a + * global tone mapping curve to the image. + */ + +/** + * \var WdrStrength + * \brief Specify the strength of the wdr algorithm. The exact meaning of this + * value is specific to the algorithm in use. Usually a value of 0 means no + * global tone mapping is applied. A values of 1 is the default value and + * the correct value for most scenes. A value above 1 increases the global + * tone mapping effect and can lead to unrealistic image effects. + */ + +/** + * \var WdrMaxBrightPixels + * \brief Percentage of allowed (nearly) saturated pixels. The WDR algorithm + * reduces the WdrExposureValue until the amount of pixels that are close + * to saturation is lower than this value. + */ + +/** + * \var LensDewarpEnable + * \brief Enable or disable lens dewarping. + */ + +/** + * \var LensShadingCorrectionEnable + * \brief Enable or disable the lens shading correction. + */ + +/** + * \var Hue + * \brief Adjusts the image hue (colour rotation) in degrees, as defined in + * the HSL/HSV colour model. + * + * The value represents a rotation around the hue circle in HSL/HSV space: + * positive values rotate hues clockwise (for example a +60° turns + * Red hues to Yellow hues), and negative values rotate counter-clockwise + * (a -60° turns Red hues to Magenta hues). + * + * The nominal range is [-180, 180], where 0° leaves hues unchanged and the + * range wraps around continuously, with 180° == -180°. + */ + +/** + * \brief Namespace for draft controls + */ +namespace draft { + +/** + * \enum AePrecaptureTriggerEnum + * \brief Supported AePrecaptureTrigger values + * + * \var AePrecaptureTriggerIdle + * \brief The trigger is idle. + * + * \var AePrecaptureTriggerStart + * \brief The pre-capture AE metering is started by the camera. + * + * \var AePrecaptureTriggerCancel + * \brief The camera will cancel any active or completed metering sequence. + * The AE algorithm is reset to its initial state. + */ + +/** + * \var AePrecaptureTriggerValues + * \brief List of all AePrecaptureTrigger supported values + */ + +/** + * \var AePrecaptureTriggerNameValueMap + * \brief Map of all AePrecaptureTrigger supported value names (in std::string format) to value + */ + +/** + * \var AePrecaptureTrigger + * \brief Control for AE metering trigger. Currently identical to + * ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER. + * + * Whether the camera device will trigger a precapture metering sequence + * when it processes this request. + */ + +/** + * \enum NoiseReductionModeEnum + * \brief Supported NoiseReductionMode values + * + * \var NoiseReductionModeOff + * \brief No noise reduction is applied + * + * \var NoiseReductionModeFast + * \brief Noise reduction is applied without reducing the frame rate. + * + * \var NoiseReductionModeHighQuality + * \brief High quality noise reduction at the expense of frame rate. + * + * \var NoiseReductionModeMinimal + * \brief Minimal noise reduction is applied without reducing the frame rate. + * + * \var NoiseReductionModeZSL + * \brief Noise reduction is applied at different levels to different streams. + */ + +/** + * \var NoiseReductionModeValues + * \brief List of all NoiseReductionMode supported values + */ + +/** + * \var NoiseReductionModeNameValueMap + * \brief Map of all NoiseReductionMode supported value names (in std::string format) to value + */ + +/** + * \var NoiseReductionMode + * \brief Control to select the noise reduction algorithm mode. Currently + * identical to ANDROID_NOISE_REDUCTION_MODE. + * + * Mode of operation for the noise reduction algorithm. + */ + +/** + * \enum ColorCorrectionAberrationModeEnum + * \brief Supported ColorCorrectionAberrationMode values + * + * \var ColorCorrectionAberrationOff + * \brief No aberration correction is applied. + * + * \var ColorCorrectionAberrationFast + * \brief Aberration correction will not slow down the frame rate. + * + * \var ColorCorrectionAberrationHighQuality + * \brief High quality aberration correction which might reduce the frame + * rate. + */ + +/** + * \var ColorCorrectionAberrationModeValues + * \brief List of all ColorCorrectionAberrationMode supported values + */ + +/** + * \var ColorCorrectionAberrationModeNameValueMap + * \brief Map of all ColorCorrectionAberrationMode supported value names (in std::string format) to value + */ + +/** + * \var ColorCorrectionAberrationMode + * \brief Control to select the color correction aberration mode. Currently + * identical to ANDROID_COLOR_CORRECTION_ABERRATION_MODE. + * + * Mode of operation for the chromatic aberration correction algorithm. + */ + +/** + * \enum AwbStateEnum + * \brief Supported AwbState values + * + * \var AwbStateInactive + * \brief The AWB algorithm is inactive. + * + * \var AwbStateSearching + * \brief The AWB algorithm has not converged yet. + * + * \var AwbConverged + * \brief The AWB algorithm has converged. + * + * \var AwbLocked + * \brief The AWB algorithm is locked. + */ + +/** + * \var AwbStateValues + * \brief List of all AwbState supported values + */ + +/** + * \var AwbStateNameValueMap + * \brief Map of all AwbState supported value names (in std::string format) to value + */ + +/** + * \var AwbState + * \brief Control to report the current AWB algorithm state. Currently identical + * to ANDROID_CONTROL_AWB_STATE. + * + * Current state of the AWB algorithm. + */ + +/** + * \var SensorRollingShutterSkew + * \brief Control to report the time between the start of exposure of the first + * row and the start of exposure of the last row. Currently identical to + * ANDROID_SENSOR_ROLLING_SHUTTER_SKEW + */ + +/** + * \enum LensShadingMapModeEnum + * \brief Supported LensShadingMapMode values + * + * \var LensShadingMapModeOff + * \brief No lens shading map mode is available. + * + * \var LensShadingMapModeOn + * \brief The lens shading map mode is available. + */ + +/** + * \var LensShadingMapModeValues + * \brief List of all LensShadingMapMode supported values + */ + +/** + * \var LensShadingMapModeNameValueMap + * \brief Map of all LensShadingMapMode supported value names (in std::string format) to value + */ + +/** + * \var LensShadingMapMode + * \brief Control to report if the lens shading map is available. Currently + * identical to ANDROID_STATISTICS_LENS_SHADING_MAP_MODE. + */ + +/** + * \var PipelineDepth + * \brief Specifies the number of pipeline stages the frame went through from when + * it was exposed to when the final completed result was available to the + * framework. Always less than or equal to PipelineMaxDepth. Currently + * identical to ANDROID_REQUEST_PIPELINE_DEPTH. + * + * The typical value for this control is 3 as a frame is first exposed, + * captured and then processed in a single pass through the ISP. Any + * additional processing step performed after the ISP pass (in example face + * detection, additional format conversions etc) count as an additional + * pipeline stage. + */ + +/** + * \var MaxLatency + * \brief The maximum number of frames that can occur after a request (different + * than the previous) has been submitted, and before the result's state + * becomes synchronized. A value of -1 indicates unknown latency, and 0 + * indicates per-frame control. Currently identical to + * ANDROID_SYNC_MAX_LATENCY. + */ + +/** + * \enum TestPatternModeEnum + * \brief Supported TestPatternMode values + * + * \var TestPatternModeOff + * \brief No test pattern mode is used. The camera device returns frames from + * the image sensor. + * + * \var TestPatternModeSolidColor + * \brief Each pixel in [R, G_even, G_odd, B] is replaced by its respective + * color channel provided in test pattern data. + * \todo Add control for test pattern data. + * + * \var TestPatternModeColorBars + * \brief All pixel data is replaced with an 8-bar color pattern. The vertical + * bars (left-to-right) are as follows; white, yellow, cyan, green, + * magenta, red, blue and black. Each bar should take up 1/8 of the + * sensor pixel array width. When this is not possible, the bar size + * should be rounded down to the nearest integer and the pattern can + * repeat on the right side. Each bar's height must always take up the + * full sensor pixel array height. + * + * \var TestPatternModeColorBarsFadeToGray + * \brief The test pattern is similar to TestPatternModeColorBars, + * except that each bar should start at its specified color at the top + * and fade to gray at the bottom. Furthermore each bar is further + * subdevided into a left and right half. The left half should have a + * smooth gradient, and the right half should have a quantized + * gradient. In particular, the right half's should consist of blocks + * of the same color for 1/16th active sensor pixel array width. The + * least significant bits in the quantized gradient should be copied + * from the most significant bits of the smooth gradient. The height of + * each bar should always be a multiple of 128. When this is not the + * case, the pattern should repeat at the bottom of the image. + * + * \var TestPatternModePn9 + * \brief All pixel data is replaced by a pseudo-random sequence generated + * from a PN9 512-bit sequence (typically implemented in hardware with + * a linear feedback shift register). The generator should be reset at + * the beginning of each frame, and thus each subsequent raw frame with + * this test pattern should be exactly the same as the last. + * + * \var TestPatternModeCustom1 + * \brief The first custom test pattern. All custom patterns that are + * available only on this camera device are at least this numeric + * value. All of the custom test patterns will be static (that is the + * raw image must not vary from frame to frame). + */ + +/** + * \var TestPatternModeValues + * \brief List of all TestPatternMode supported values + */ + +/** + * \var TestPatternModeNameValueMap + * \brief Map of all TestPatternMode supported value names (in std::string format) to value + */ + +/** + * \var TestPatternMode + * \brief Control to select the test pattern mode. Currently identical to + * ANDROID_SENSOR_TEST_PATTERN_MODE. + */ + +/** + * \enum FaceDetectModeEnum + * \brief Supported FaceDetectMode values + * + * \var FaceDetectModeOff + * \brief Pipeline doesn't perform face detection and doesn't report any + * control related to face detection. + * + * \var FaceDetectModeSimple + * \brief Pipeline performs face detection and reports the + * FaceDetectFaceRectangles and FaceDetectFaceScores controls for each + * detected face. FaceDetectFaceLandmarks and FaceDetectFaceIds are + * optional. + * + * \var FaceDetectModeFull + * \brief Pipeline performs face detection and reports all the controls + * related to face detection including FaceDetectFaceRectangles, + * FaceDetectFaceScores, FaceDetectFaceLandmarks, and + * FaceDeteceFaceIds for each detected face. + */ + +/** + * \var FaceDetectModeValues + * \brief List of all FaceDetectMode supported values + */ + +/** + * \var FaceDetectModeNameValueMap + * \brief Map of all FaceDetectMode supported value names (in std::string format) to value + */ + +/** + * \var FaceDetectMode + * \brief Control to select the face detection mode used by the pipeline. + * + * Currently identical to ANDROID_STATISTICS_FACE_DETECT_MODE. + * + * \sa FaceDetectFaceRectangles + * \sa FaceDetectFaceScores + * \sa FaceDetectFaceLandmarks + * \sa FaceDetectFaceIds + */ + +/** + * \var FaceDetectFaceRectangles + * \brief Boundary rectangles of the detected faces. The number of values is + * the number of detected faces. + * + * The FaceDetectFaceRectangles control can only be returned in metadata. + * + * Currently identical to ANDROID_STATISTICS_FACE_RECTANGLES. + */ + +/** + * \var FaceDetectFaceScores + * \brief Confidence score of each of the detected faces. The range of score is + * [0, 100]. The number of values should be the number of faces reported + * in FaceDetectFaceRectangles. + * + * The FaceDetectFaceScores control can only be returned in metadata. + * + * Currently identical to ANDROID_STATISTICS_FACE_SCORES. + */ + +/** + * \var FaceDetectFaceLandmarks + * \brief Array of human face landmark coordinates in format [..., left_eye_i, + * right_eye_i, mouth_i, left_eye_i+1, ...], with i = index of face. The + * number of values should be 3 * the number of faces reported in + * FaceDetectFaceRectangles. + * + * The FaceDetectFaceLandmarks control can only be returned in metadata. + * + * Currently identical to ANDROID_STATISTICS_FACE_LANDMARKS. + */ + +/** + * \var FaceDetectFaceIds + * \brief Each detected face is given a unique ID that is valid for as long as the + * face is visible to the camera device. A face that leaves the field of + * view and later returns may be assigned a new ID. The number of values + * should be the number of faces reported in FaceDetectFaceRectangles. + * + * The FaceDetectFaceIds control can only be returned in metadata. + * + * Currently identical to ANDROID_STATISTICS_FACE_IDS. + */ + +} /* namespace draft */ + +/** + * \brief Namespace for rpi controls + */ +namespace rpi { + +/** + * \var StatsOutputEnable + * \brief Toggles the Raspberry Pi IPA to output the hardware generated statistics. + * + * When this control is set to true, the IPA outputs a binary dump of the + * hardware generated statistics through the Request metadata in the + * Bcm2835StatsOutput control. + * + * \sa Bcm2835StatsOutput + */ + +/** + * \var Bcm2835StatsOutput + * \brief Span of the BCM2835 ISP generated statistics for the current frame. + * + * This is sent in the Request metadata if the StatsOutputEnable is set to + * true. The statistics struct definition can be found in + * include/linux/bcm2835-isp.h. + * + * \sa StatsOutputEnable + */ + +/** + * \var ScalerCrops + * \brief An array of rectangles, where each singular value has identical + * functionality to the ScalerCrop control. This control allows the + * Raspberry Pi pipeline handler to control individual scaler crops per + * output stream. + * + * The order of rectangles passed into the control must match the order of + * streams configured by the application. The pipeline handler will only + * configure crop retangles up-to the number of output streams configured. + * All subsequent rectangles passed into this control are ignored by the + * pipeline handler. + * + * If both rpi::ScalerCrops and ScalerCrop controls are present in a + * ControlList, the latter is discarded, and crops are obtained from this + * control. + * + * Note that using different crop rectangles for each output stream with + * this control is only applicable on the Pi5/PiSP platform. This control + * should also be considered temporary/draft and will be replaced with + * official libcamera API support for per-stream controls in the future. + * + * \sa ScalerCrop + */ + +/** + * \var PispStatsOutput + * \brief Span of the PiSP Frontend ISP generated statistics for the current + * frame. This is sent in the Request metadata if the StatsOutputEnable is + * set to true. The statistics struct definition can be found in + * https://github.com/raspberrypi/libpisp/blob/main/src/libpisp/frontend/pisp_statistics.h + * + * \sa StatsOutputEnable + */ + +/** + * \enum SyncModeEnum + * \brief Supported SyncMode values + * + * \var SyncModeOff + * \brief Disable sync mode. + * + * \var SyncModeServer + * \brief Enable sync mode, act as server. The server broadcasts timing + * messages to any clients that are listening, so that the clients can + * synchronise their camera frames with the server's. + * + * \var SyncModeClient + * \brief Enable sync mode, act as client. A client listens for any server + * messages, and arranges for its camera frames to synchronise as + * closely as possible with the server's. Many clients can listen out + * for the same server. Clients can also be started ahead of any + * servers, causing them merely to wait for the server to start. + */ + +/** + * \var SyncModeValues + * \brief List of all SyncMode supported values + */ + +/** + * \var SyncModeNameValueMap + * \brief Map of all SyncMode supported value names (in std::string format) to value + */ + +/** + * \var SyncMode + * \brief Enable or disable camera synchronisation ("sync") mode. + * + * When sync mode is enabled, a camera will synchronise frames temporally + * with other cameras, either attached to the same device or a different + * one. There should be one "server" device, which broadcasts timing + * information to one or more "clients". Communication is one-way, from + * server to clients only, and it is only clients that adjust their frame + * timings to match the server. + * + * Sync mode requires all cameras to be running at (as far as possible) the + * same fixed framerate. Clients may continue to make adjustments to keep + * their cameras synchronised with the server for the duration of the + * session, though any updates after the initial ones should remain small. + * + * \sa SyncReady + * \sa SyncTimer + * \sa SyncFrames + */ + +/** + * \var SyncReady + * \brief When using the camera synchronisation algorithm, the server broadcasts + * timing information to the clients. This also includes the time (some + * number of frames in the future, called the "ready time") at which the + * server will signal its controlling application, using this control, to + * start using the image frames. + * + * The client receives the "ready time" from the server, and will signal + * its application to start using the frames at this same moment. + * + * While this control value is false, applications (on both client and + * server) should continue to wait, and not use the frames. + * + * Once this value becomes true, it means that this is the first frame + * where the server and its clients have agreed that they will both be + * synchronised and that applications should begin consuming frames. + * Thereafter, this control will continue to signal the value true for + * the rest of the session. + * + * \sa SyncMode + * \sa SyncTimer + * \sa SyncFrames + */ + +/** + * \var SyncTimer + * \brief This reports the amount of time, in microseconds, until the "ready + * time", at which the server and client will signal their controlling + * applications that the frames are now synchronised and should be + * used. The value may be refined slightly over time, becoming more precise + * as the "ready time" approaches. + * + * Servers always report this value, whereas clients will omit this control + * until they have received a message from the server that enables them to + * calculate it. + * + * Normally the value will start positive (the "ready time" is in the + * future), and decrease towards zero, before becoming negative (the "ready + * time" has elapsed). So there should be just one frame where the timer + * value is, or is very close to, zero - the one for which the SyncReady + * control becomes true. At this moment, the value indicates how closely + * synchronised the client believes it is with the server. + * + * But note that if frames are being dropped, then the "near zero" valued + * frame, or indeed any other, could be skipped. In these cases the timer + * value allows an application to deduce that this has happened. + * + * \sa SyncMode + * \sa SyncReady + * \sa SyncFrames + */ + +/** + * \var SyncFrames + * \brief The number of frames the server should wait, after enabling + * SyncModeServer, before signalling (via the SyncReady control) that + * frames should be used. This therefore determines the "ready time" for + * all synchronised cameras. + * + * This control value should be set only for the device that is to act as + * the server, before or at the same moment at which SyncModeServer is + * enabled. + * + * \sa SyncMode + * \sa SyncReady + * \sa SyncTimer + */ + +/** + * \var CnnOutputTensor + * \brief This control returns a span of floating point values that represent the + * output tensors from a Convolutional Neural Network (CNN). The size and + * format of this array of values is entirely dependent on the neural + * network used, and further post-processing may need to be performed at + * the application level to generate the final desired output. This control + * is agnostic of the hardware or software used to generate the output + * tensors. + * + * The structure of the span is described by the CnnOutputTensorInfo + * control. + * + * \sa CnnOutputTensorInfo + */ + +/** + * \var CnnOutputTensorInfo + * \brief This control returns the structure of the CnnOutputTensor. This structure + * takes the following form: + * + * constexpr unsigned int NetworkNameLen = 64; + * constexpr unsigned int MaxNumTensors = 8; + * constexpr unsigned int MaxNumDimensions = 8; + * + * struct CnnOutputTensorInfo { + * char networkName[NetworkNameLen]; + * uint32_t numTensors; + * OutputTensorInfo info[MaxNumTensors]; + * uint8_t frameCount; + * }; + * + * with + * + * struct OutputTensorInfo { + * uint32_t tensorDataNum; + * uint32_t numDimensions; + * uint16_t size[MaxNumDimensions]; + * }; + * + * networkName is the name of the CNN used, + * numTensors is the number of output tensors returned, + * tensorDataNum gives the number of elements in each output tensor, + * numDimensions gives the dimensionality of each output tensor, + * size gives the size of each dimension in each output tensor. + * + * \sa CnnOutputTensor + */ + +/** + * \var CnnEnableInputTensor + * \brief Boolean to control if the IPA returns the input tensor used by the CNN + * to generate the output tensors via the CnnInputTensor control. Because + * the input tensor may be relatively large, for efficiency reason avoid + * enabling input tensor output unless required for debugging purposes. + * + * \sa CnnInputTensor + */ + +/** + * \var CnnInputTensor + * \brief This control returns a span of uint8_t pixel values that represent the + * input tensor for a Convolutional Neural Network (CNN). The size and + * format of this array of values is entirely dependent on the neural + * network used, and further post-processing (e.g. pixel normalisations) may + * need to be performed at the application level to generate the final input + * image. + * + * The structure of the span is described by the CnnInputTensorInfo + * control. + * + * \sa CnnInputTensorInfo + */ + +/** + * \var CnnInputTensorInfo + * \brief This control returns the structure of the CnnInputTensor. This structure + * takes the following form: + * + * constexpr unsigned int NetworkNameLen = 64; + * + * struct CnnInputTensorInfo { + * char networkName[NetworkNameLen]; + * uint32_t width; + * uint32_t height; + * uint32_t numChannels; + * uint8_t frameCount; + * }; + * + * where + * + * networkName is the name of the CNN used, + * width and height are the input tensor image width and height in pixels, + * numChannels is the number of channels in the input tensor image. + * + * \sa CnnInputTensor + */ + +/** + * \var CnnKpiInfo + * \brief This control returns performance metrics for the CNN processing stage. + * Two values are returned in this span, the runtime of the CNN/DNN stage + * and the DSP stage in milliseconds. + */ + +} /* namespace rpi */ + +/** + * \brief Namespace for debug controls + */ +namespace debug { + +} /* namespace debug */ + + +#ifndef __DOXYGEN__ +/* + * Keep the controls definitions hidden from doxygen as it incorrectly parses + * them as functions. + */ + +extern const Control AeEnable(AE_ENABLE, "AeEnable", "libcamera", ControlId::Direction::In); + +extern const std::array AeStateValues = { + static_cast(AeStateIdle), + static_cast(AeStateSearching), + static_cast(AeStateConverged), +}; +extern const std::map AeStateNameValueMap = { + { "AeStateIdle", AeStateIdle }, + { "AeStateSearching", AeStateSearching }, + { "AeStateConverged", AeStateConverged }, +}; +extern const Control AeState(AE_STATE, "AeState", "libcamera", ControlId::Direction::Out, AeStateNameValueMap); + +extern const std::array AeMeteringModeValues = { + static_cast(MeteringCentreWeighted), + static_cast(MeteringSpot), + static_cast(MeteringMatrix), + static_cast(MeteringCustom), +}; +extern const std::map AeMeteringModeNameValueMap = { + { "MeteringCentreWeighted", MeteringCentreWeighted }, + { "MeteringSpot", MeteringSpot }, + { "MeteringMatrix", MeteringMatrix }, + { "MeteringCustom", MeteringCustom }, +}; +extern const Control AeMeteringMode(AE_METERING_MODE, "AeMeteringMode", "libcamera", ControlId::Direction::In | ControlId::Direction::Out, AeMeteringModeNameValueMap); + +extern const std::array AeConstraintModeValues = { + static_cast(ConstraintNormal), + static_cast(ConstraintHighlight), + static_cast(ConstraintShadows), + static_cast(ConstraintCustom), +}; +extern const std::map AeConstraintModeNameValueMap = { + { "ConstraintNormal", ConstraintNormal }, + { "ConstraintHighlight", ConstraintHighlight }, + { "ConstraintShadows", ConstraintShadows }, + { "ConstraintCustom", ConstraintCustom }, +}; +extern const Control AeConstraintMode(AE_CONSTRAINT_MODE, "AeConstraintMode", "libcamera", ControlId::Direction::In | ControlId::Direction::Out, AeConstraintModeNameValueMap); + +extern const std::array AeExposureModeValues = { + static_cast(ExposureNormal), + static_cast(ExposureShort), + static_cast(ExposureLong), + static_cast(ExposureCustom), +}; +extern const std::map AeExposureModeNameValueMap = { + { "ExposureNormal", ExposureNormal }, + { "ExposureShort", ExposureShort }, + { "ExposureLong", ExposureLong }, + { "ExposureCustom", ExposureCustom }, +}; +extern const Control AeExposureMode(AE_EXPOSURE_MODE, "AeExposureMode", "libcamera", ControlId::Direction::In | ControlId::Direction::Out, AeExposureModeNameValueMap); + +extern const Control ExposureValue(EXPOSURE_VALUE, "ExposureValue", "libcamera", ControlId::Direction::In | ControlId::Direction::Out); + +extern const Control ExposureTime(EXPOSURE_TIME, "ExposureTime", "libcamera", ControlId::Direction::In | ControlId::Direction::Out); + +extern const std::array ExposureTimeModeValues = { + static_cast(ExposureTimeModeAuto), + static_cast(ExposureTimeModeManual), +}; +extern const std::map ExposureTimeModeNameValueMap = { + { "ExposureTimeModeAuto", ExposureTimeModeAuto }, + { "ExposureTimeModeManual", ExposureTimeModeManual }, +}; +extern const Control ExposureTimeMode(EXPOSURE_TIME_MODE, "ExposureTimeMode", "libcamera", ControlId::Direction::In | ControlId::Direction::Out, ExposureTimeModeNameValueMap); + +extern const Control AnalogueGain(ANALOGUE_GAIN, "AnalogueGain", "libcamera", ControlId::Direction::In | ControlId::Direction::Out); + +extern const std::array AnalogueGainModeValues = { + static_cast(AnalogueGainModeAuto), + static_cast(AnalogueGainModeManual), +}; +extern const std::map AnalogueGainModeNameValueMap = { + { "AnalogueGainModeAuto", AnalogueGainModeAuto }, + { "AnalogueGainModeManual", AnalogueGainModeManual }, +}; +extern const Control AnalogueGainMode(ANALOGUE_GAIN_MODE, "AnalogueGainMode", "libcamera", ControlId::Direction::In | ControlId::Direction::Out, AnalogueGainModeNameValueMap); + +extern const std::array AeFlickerModeValues = { + static_cast(FlickerOff), + static_cast(FlickerManual), + static_cast(FlickerAuto), +}; +extern const std::map AeFlickerModeNameValueMap = { + { "FlickerOff", FlickerOff }, + { "FlickerManual", FlickerManual }, + { "FlickerAuto", FlickerAuto }, +}; +extern const Control AeFlickerMode(AE_FLICKER_MODE, "AeFlickerMode", "libcamera", ControlId::Direction::In | ControlId::Direction::Out, AeFlickerModeNameValueMap); + +extern const Control AeFlickerPeriod(AE_FLICKER_PERIOD, "AeFlickerPeriod", "libcamera", ControlId::Direction::In | ControlId::Direction::Out); + +extern const Control AeFlickerDetected(AE_FLICKER_DETECTED, "AeFlickerDetected", "libcamera", ControlId::Direction::Out); + +extern const Control Brightness(BRIGHTNESS, "Brightness", "libcamera", ControlId::Direction::In | ControlId::Direction::Out); + +extern const Control Contrast(CONTRAST, "Contrast", "libcamera", ControlId::Direction::In | ControlId::Direction::Out); + +extern const Control Lux(LUX, "Lux", "libcamera", ControlId::Direction::Out); + +extern const Control AwbEnable(AWB_ENABLE, "AwbEnable", "libcamera", ControlId::Direction::In | ControlId::Direction::Out); + +extern const std::array AwbModeValues = { + static_cast(AwbAuto), + static_cast(AwbIncandescent), + static_cast(AwbTungsten), + static_cast(AwbFluorescent), + static_cast(AwbIndoor), + static_cast(AwbDaylight), + static_cast(AwbCloudy), + static_cast(AwbCustom), +}; +extern const std::map AwbModeNameValueMap = { + { "AwbAuto", AwbAuto }, + { "AwbIncandescent", AwbIncandescent }, + { "AwbTungsten", AwbTungsten }, + { "AwbFluorescent", AwbFluorescent }, + { "AwbIndoor", AwbIndoor }, + { "AwbDaylight", AwbDaylight }, + { "AwbCloudy", AwbCloudy }, + { "AwbCustom", AwbCustom }, +}; +extern const Control AwbMode(AWB_MODE, "AwbMode", "libcamera", ControlId::Direction::In | ControlId::Direction::Out, AwbModeNameValueMap); + +extern const Control AwbLocked(AWB_LOCKED, "AwbLocked", "libcamera", ControlId::Direction::Out); + +extern const Control> ColourGains(COLOUR_GAINS, "ColourGains", "libcamera", ControlId::Direction::In | ControlId::Direction::Out); + +extern const Control ColourTemperature(COLOUR_TEMPERATURE, "ColourTemperature", "libcamera", ControlId::Direction::Out); + +extern const Control Saturation(SATURATION, "Saturation", "libcamera", ControlId::Direction::In | ControlId::Direction::Out); + +extern const Control> SensorBlackLevels(SENSOR_BLACK_LEVELS, "SensorBlackLevels", "libcamera", ControlId::Direction::Out); + +extern const Control Sharpness(SHARPNESS, "Sharpness", "libcamera", ControlId::Direction::In | ControlId::Direction::Out); + +extern const Control FocusFoM(FOCUS_FO_M, "FocusFoM", "libcamera", ControlId::Direction::Out); + +extern const Control> ColourCorrectionMatrix(COLOUR_CORRECTION_MATRIX, "ColourCorrectionMatrix", "libcamera", ControlId::Direction::In | ControlId::Direction::Out); + +extern const Control ScalerCrop(SCALER_CROP, "ScalerCrop", "libcamera", ControlId::Direction::In | ControlId::Direction::Out); + +extern const Control DigitalGain(DIGITAL_GAIN, "DigitalGain", "libcamera", ControlId::Direction::In | ControlId::Direction::Out); + +extern const Control FrameDuration(FRAME_DURATION, "FrameDuration", "libcamera", ControlId::Direction::Out); + +extern const Control> FrameDurationLimits(FRAME_DURATION_LIMITS, "FrameDurationLimits", "libcamera", ControlId::Direction::In | ControlId::Direction::Out); + +extern const Control SensorTemperature(SENSOR_TEMPERATURE, "SensorTemperature", "libcamera", ControlId::Direction::Out); + +extern const Control SensorTimestamp(SENSOR_TIMESTAMP, "SensorTimestamp", "libcamera", ControlId::Direction::Out); + +extern const std::array AfModeValues = { + static_cast(AfModeManual), + static_cast(AfModeAuto), + static_cast(AfModeContinuous), +}; +extern const std::map AfModeNameValueMap = { + { "AfModeManual", AfModeManual }, + { "AfModeAuto", AfModeAuto }, + { "AfModeContinuous", AfModeContinuous }, +}; +extern const Control AfMode(AF_MODE, "AfMode", "libcamera", ControlId::Direction::In | ControlId::Direction::Out, AfModeNameValueMap); + +extern const std::array AfRangeValues = { + static_cast(AfRangeNormal), + static_cast(AfRangeMacro), + static_cast(AfRangeFull), +}; +extern const std::map AfRangeNameValueMap = { + { "AfRangeNormal", AfRangeNormal }, + { "AfRangeMacro", AfRangeMacro }, + { "AfRangeFull", AfRangeFull }, +}; +extern const Control AfRange(AF_RANGE, "AfRange", "libcamera", ControlId::Direction::In | ControlId::Direction::Out, AfRangeNameValueMap); + +extern const std::array AfSpeedValues = { + static_cast(AfSpeedNormal), + static_cast(AfSpeedFast), +}; +extern const std::map AfSpeedNameValueMap = { + { "AfSpeedNormal", AfSpeedNormal }, + { "AfSpeedFast", AfSpeedFast }, +}; +extern const Control AfSpeed(AF_SPEED, "AfSpeed", "libcamera", ControlId::Direction::In | ControlId::Direction::Out, AfSpeedNameValueMap); + +extern const std::array AfMeteringValues = { + static_cast(AfMeteringAuto), + static_cast(AfMeteringWindows), +}; +extern const std::map AfMeteringNameValueMap = { + { "AfMeteringAuto", AfMeteringAuto }, + { "AfMeteringWindows", AfMeteringWindows }, +}; +extern const Control AfMetering(AF_METERING, "AfMetering", "libcamera", ControlId::Direction::In | ControlId::Direction::Out, AfMeteringNameValueMap); + +extern const Control> AfWindows(AF_WINDOWS, "AfWindows", "libcamera", ControlId::Direction::In | ControlId::Direction::Out); + +extern const std::array AfTriggerValues = { + static_cast(AfTriggerStart), + static_cast(AfTriggerCancel), +}; +extern const std::map AfTriggerNameValueMap = { + { "AfTriggerStart", AfTriggerStart }, + { "AfTriggerCancel", AfTriggerCancel }, +}; +extern const Control AfTrigger(AF_TRIGGER, "AfTrigger", "libcamera", ControlId::Direction::In, AfTriggerNameValueMap); + +extern const std::array AfPauseValues = { + static_cast(AfPauseImmediate), + static_cast(AfPauseDeferred), + static_cast(AfPauseResume), +}; +extern const std::map AfPauseNameValueMap = { + { "AfPauseImmediate", AfPauseImmediate }, + { "AfPauseDeferred", AfPauseDeferred }, + { "AfPauseResume", AfPauseResume }, +}; +extern const Control AfPause(AF_PAUSE, "AfPause", "libcamera", ControlId::Direction::In, AfPauseNameValueMap); + +extern const Control LensPosition(LENS_POSITION, "LensPosition", "libcamera", ControlId::Direction::In | ControlId::Direction::Out); + +extern const std::array AfStateValues = { + static_cast(AfStateIdle), + static_cast(AfStateScanning), + static_cast(AfStateFocused), + static_cast(AfStateFailed), +}; +extern const std::map AfStateNameValueMap = { + { "AfStateIdle", AfStateIdle }, + { "AfStateScanning", AfStateScanning }, + { "AfStateFocused", AfStateFocused }, + { "AfStateFailed", AfStateFailed }, +}; +extern const Control AfState(AF_STATE, "AfState", "libcamera", ControlId::Direction::Out, AfStateNameValueMap); + +extern const std::array AfPauseStateValues = { + static_cast(AfPauseStateRunning), + static_cast(AfPauseStatePausing), + static_cast(AfPauseStatePaused), +}; +extern const std::map AfPauseStateNameValueMap = { + { "AfPauseStateRunning", AfPauseStateRunning }, + { "AfPauseStatePausing", AfPauseStatePausing }, + { "AfPauseStatePaused", AfPauseStatePaused }, +}; +extern const Control AfPauseState(AF_PAUSE_STATE, "AfPauseState", "libcamera", ControlId::Direction::Out, AfPauseStateNameValueMap); + +extern const std::array HdrModeValues = { + static_cast(HdrModeOff), + static_cast(HdrModeMultiExposureUnmerged), + static_cast(HdrModeMultiExposure), + static_cast(HdrModeSingleExposure), + static_cast(HdrModeNight), +}; +extern const std::map HdrModeNameValueMap = { + { "HdrModeOff", HdrModeOff }, + { "HdrModeMultiExposureUnmerged", HdrModeMultiExposureUnmerged }, + { "HdrModeMultiExposure", HdrModeMultiExposure }, + { "HdrModeSingleExposure", HdrModeSingleExposure }, + { "HdrModeNight", HdrModeNight }, +}; +extern const Control HdrMode(HDR_MODE, "HdrMode", "libcamera", ControlId::Direction::In | ControlId::Direction::Out, HdrModeNameValueMap); + +extern const std::array HdrChannelValues = { + static_cast(HdrChannelNone), + static_cast(HdrChannelShort), + static_cast(HdrChannelMedium), + static_cast(HdrChannelLong), +}; +extern const std::map HdrChannelNameValueMap = { + { "HdrChannelNone", HdrChannelNone }, + { "HdrChannelShort", HdrChannelShort }, + { "HdrChannelMedium", HdrChannelMedium }, + { "HdrChannelLong", HdrChannelLong }, +}; +extern const Control HdrChannel(HDR_CHANNEL, "HdrChannel", "libcamera", ControlId::Direction::Out, HdrChannelNameValueMap); + +extern const Control Gamma(GAMMA, "Gamma", "libcamera", ControlId::Direction::In | ControlId::Direction::Out); + +extern const Control DebugMetadataEnable(DEBUG_METADATA_ENABLE, "DebugMetadataEnable", "libcamera", ControlId::Direction::In | ControlId::Direction::Out); + +extern const Control FrameWallClock(FRAME_WALL_CLOCK, "FrameWallClock", "libcamera", ControlId::Direction::Out); + +extern const std::array WdrModeValues = { + static_cast(WdrOff), + static_cast(WdrLinear), + static_cast(WdrPower), + static_cast(WdrExponential), + static_cast(WdrHistogramEqualization), +}; +extern const std::map WdrModeNameValueMap = { + { "WdrOff", WdrOff }, + { "WdrLinear", WdrLinear }, + { "WdrPower", WdrPower }, + { "WdrExponential", WdrExponential }, + { "WdrHistogramEqualization", WdrHistogramEqualization }, +}; +extern const Control WdrMode(WDR_MODE, "WdrMode", "libcamera", ControlId::Direction::In | ControlId::Direction::Out, WdrModeNameValueMap); + +extern const Control WdrStrength(WDR_STRENGTH, "WdrStrength", "libcamera", ControlId::Direction::In); + +extern const Control WdrMaxBrightPixels(WDR_MAX_BRIGHT_PIXELS, "WdrMaxBrightPixels", "libcamera", ControlId::Direction::In); + +extern const Control LensDewarpEnable(LENS_DEWARP_ENABLE, "LensDewarpEnable", "libcamera", ControlId::Direction::In | ControlId::Direction::Out); + +extern const Control LensShadingCorrectionEnable(LENS_SHADING_CORRECTION_ENABLE, "LensShadingCorrectionEnable", "libcamera", ControlId::Direction::In | ControlId::Direction::Out); + +extern const Control Hue(HUE, "Hue", "libcamera", ControlId::Direction::In | ControlId::Direction::Out); + + + +namespace draft { + +extern const std::array AePrecaptureTriggerValues = { + static_cast(AePrecaptureTriggerIdle), + static_cast(AePrecaptureTriggerStart), + static_cast(AePrecaptureTriggerCancel), +}; +extern const std::map AePrecaptureTriggerNameValueMap = { + { "AePrecaptureTriggerIdle", AePrecaptureTriggerIdle }, + { "AePrecaptureTriggerStart", AePrecaptureTriggerStart }, + { "AePrecaptureTriggerCancel", AePrecaptureTriggerCancel }, +}; +extern const Control AePrecaptureTrigger(AE_PRECAPTURE_TRIGGER, "AePrecaptureTrigger", "draft", ControlId::Direction::In | ControlId::Direction::Out, AePrecaptureTriggerNameValueMap); + +extern const std::array NoiseReductionModeValues = { + static_cast(NoiseReductionModeOff), + static_cast(NoiseReductionModeFast), + static_cast(NoiseReductionModeHighQuality), + static_cast(NoiseReductionModeMinimal), + static_cast(NoiseReductionModeZSL), +}; +extern const std::map NoiseReductionModeNameValueMap = { + { "NoiseReductionModeOff", NoiseReductionModeOff }, + { "NoiseReductionModeFast", NoiseReductionModeFast }, + { "NoiseReductionModeHighQuality", NoiseReductionModeHighQuality }, + { "NoiseReductionModeMinimal", NoiseReductionModeMinimal }, + { "NoiseReductionModeZSL", NoiseReductionModeZSL }, +}; +extern const Control NoiseReductionMode(NOISE_REDUCTION_MODE, "NoiseReductionMode", "draft", ControlId::Direction::In | ControlId::Direction::Out, NoiseReductionModeNameValueMap); + +extern const std::array ColorCorrectionAberrationModeValues = { + static_cast(ColorCorrectionAberrationOff), + static_cast(ColorCorrectionAberrationFast), + static_cast(ColorCorrectionAberrationHighQuality), +}; +extern const std::map ColorCorrectionAberrationModeNameValueMap = { + { "ColorCorrectionAberrationOff", ColorCorrectionAberrationOff }, + { "ColorCorrectionAberrationFast", ColorCorrectionAberrationFast }, + { "ColorCorrectionAberrationHighQuality", ColorCorrectionAberrationHighQuality }, +}; +extern const Control ColorCorrectionAberrationMode(COLOR_CORRECTION_ABERRATION_MODE, "ColorCorrectionAberrationMode", "draft", ControlId::Direction::In | ControlId::Direction::Out, ColorCorrectionAberrationModeNameValueMap); + +extern const std::array AwbStateValues = { + static_cast(AwbStateInactive), + static_cast(AwbStateSearching), + static_cast(AwbConverged), + static_cast(AwbLocked), +}; +extern const std::map AwbStateNameValueMap = { + { "AwbStateInactive", AwbStateInactive }, + { "AwbStateSearching", AwbStateSearching }, + { "AwbConverged", AwbConverged }, + { "AwbLocked", AwbLocked }, +}; +extern const Control AwbState(AWB_STATE, "AwbState", "draft", ControlId::Direction::Out, AwbStateNameValueMap); + +extern const Control SensorRollingShutterSkew(SENSOR_ROLLING_SHUTTER_SKEW, "SensorRollingShutterSkew", "draft", ControlId::Direction::Out); + +extern const std::array LensShadingMapModeValues = { + static_cast(LensShadingMapModeOff), + static_cast(LensShadingMapModeOn), +}; +extern const std::map LensShadingMapModeNameValueMap = { + { "LensShadingMapModeOff", LensShadingMapModeOff }, + { "LensShadingMapModeOn", LensShadingMapModeOn }, +}; +extern const Control LensShadingMapMode(LENS_SHADING_MAP_MODE, "LensShadingMapMode", "draft", ControlId::Direction::In | ControlId::Direction::Out, LensShadingMapModeNameValueMap); + +extern const Control PipelineDepth(PIPELINE_DEPTH, "PipelineDepth", "draft", ControlId::Direction::Out); + +extern const Control MaxLatency(MAX_LATENCY, "MaxLatency", "draft", ControlId::Direction::Out); + +extern const std::array TestPatternModeValues = { + static_cast(TestPatternModeOff), + static_cast(TestPatternModeSolidColor), + static_cast(TestPatternModeColorBars), + static_cast(TestPatternModeColorBarsFadeToGray), + static_cast(TestPatternModePn9), + static_cast(TestPatternModeCustom1), +}; +extern const std::map TestPatternModeNameValueMap = { + { "TestPatternModeOff", TestPatternModeOff }, + { "TestPatternModeSolidColor", TestPatternModeSolidColor }, + { "TestPatternModeColorBars", TestPatternModeColorBars }, + { "TestPatternModeColorBarsFadeToGray", TestPatternModeColorBarsFadeToGray }, + { "TestPatternModePn9", TestPatternModePn9 }, + { "TestPatternModeCustom1", TestPatternModeCustom1 }, +}; +extern const Control TestPatternMode(TEST_PATTERN_MODE, "TestPatternMode", "draft", ControlId::Direction::In | ControlId::Direction::Out, TestPatternModeNameValueMap); + +extern const std::array FaceDetectModeValues = { + static_cast(FaceDetectModeOff), + static_cast(FaceDetectModeSimple), + static_cast(FaceDetectModeFull), +}; +extern const std::map FaceDetectModeNameValueMap = { + { "FaceDetectModeOff", FaceDetectModeOff }, + { "FaceDetectModeSimple", FaceDetectModeSimple }, + { "FaceDetectModeFull", FaceDetectModeFull }, +}; +extern const Control FaceDetectMode(FACE_DETECT_MODE, "FaceDetectMode", "draft", ControlId::Direction::In | ControlId::Direction::Out, FaceDetectModeNameValueMap); + +extern const Control> FaceDetectFaceRectangles(FACE_DETECT_FACE_RECTANGLES, "FaceDetectFaceRectangles", "draft", ControlId::Direction::Out); + +extern const Control> FaceDetectFaceScores(FACE_DETECT_FACE_SCORES, "FaceDetectFaceScores", "draft", ControlId::Direction::Out); + +extern const Control> FaceDetectFaceLandmarks(FACE_DETECT_FACE_LANDMARKS, "FaceDetectFaceLandmarks", "draft", ControlId::Direction::Out); + +extern const Control> FaceDetectFaceIds(FACE_DETECT_FACE_IDS, "FaceDetectFaceIds", "draft", ControlId::Direction::Out); + + + +} /* namespace draft */ + +namespace rpi { + +extern const Control StatsOutputEnable(STATS_OUTPUT_ENABLE, "StatsOutputEnable", "rpi", ControlId::Direction::In | ControlId::Direction::Out); + +extern const Control> Bcm2835StatsOutput(BCM2835_STATS_OUTPUT, "Bcm2835StatsOutput", "rpi", ControlId::Direction::Out); + +extern const Control> ScalerCrops(SCALER_CROPS, "ScalerCrops", "rpi", ControlId::Direction::Out); + +extern const Control> PispStatsOutput(PISP_STATS_OUTPUT, "PispStatsOutput", "rpi", ControlId::Direction::Out); + +extern const std::array SyncModeValues = { + static_cast(SyncModeOff), + static_cast(SyncModeServer), + static_cast(SyncModeClient), +}; +extern const std::map SyncModeNameValueMap = { + { "SyncModeOff", SyncModeOff }, + { "SyncModeServer", SyncModeServer }, + { "SyncModeClient", SyncModeClient }, +}; +extern const Control SyncMode(SYNC_MODE, "SyncMode", "rpi", ControlId::Direction::In, SyncModeNameValueMap); + +extern const Control SyncReady(SYNC_READY, "SyncReady", "rpi", ControlId::Direction::Out); + +extern const Control SyncTimer(SYNC_TIMER, "SyncTimer", "rpi", ControlId::Direction::Out); + +extern const Control SyncFrames(SYNC_FRAMES, "SyncFrames", "rpi", ControlId::Direction::In); + +extern const Control> CnnOutputTensor(CNN_OUTPUT_TENSOR, "CnnOutputTensor", "rpi", ControlId::Direction::Out); + +extern const Control> CnnOutputTensorInfo(CNN_OUTPUT_TENSOR_INFO, "CnnOutputTensorInfo", "rpi", ControlId::Direction::Out); + +extern const Control CnnEnableInputTensor(CNN_ENABLE_INPUT_TENSOR, "CnnEnableInputTensor", "rpi", ControlId::Direction::In); + +extern const Control> CnnInputTensor(CNN_INPUT_TENSOR, "CnnInputTensor", "rpi", ControlId::Direction::Out); + +extern const Control> CnnInputTensorInfo(CNN_INPUT_TENSOR_INFO, "CnnInputTensorInfo", "rpi", ControlId::Direction::Out); + +extern const Control> CnnKpiInfo(CNN_KPI_INFO, "CnnKpiInfo", "rpi", ControlId::Direction::Out); + + + +} /* namespace rpi */ + +namespace debug { + + + +} /* namespace debug */ + +#endif /* __DOXYGEN__ */ + +/** + * \brief List of all supported libcamera controls + * + * Unless otherwise stated, all controls are bi-directional, i.e. they can be + * set through Request::controls() and returned out through Request::metadata(). + */ +extern const ControlIdMap controls { + { AE_ENABLE, &AeEnable }, + { AE_STATE, &AeState }, + { AE_METERING_MODE, &AeMeteringMode }, + { AE_CONSTRAINT_MODE, &AeConstraintMode }, + { AE_EXPOSURE_MODE, &AeExposureMode }, + { EXPOSURE_VALUE, &ExposureValue }, + { EXPOSURE_TIME, &ExposureTime }, + { EXPOSURE_TIME_MODE, &ExposureTimeMode }, + { ANALOGUE_GAIN, &AnalogueGain }, + { ANALOGUE_GAIN_MODE, &AnalogueGainMode }, + { AE_FLICKER_MODE, &AeFlickerMode }, + { AE_FLICKER_PERIOD, &AeFlickerPeriod }, + { AE_FLICKER_DETECTED, &AeFlickerDetected }, + { BRIGHTNESS, &Brightness }, + { CONTRAST, &Contrast }, + { LUX, &Lux }, + { AWB_ENABLE, &AwbEnable }, + { AWB_MODE, &AwbMode }, + { AWB_LOCKED, &AwbLocked }, + { COLOUR_GAINS, &ColourGains }, + { COLOUR_TEMPERATURE, &ColourTemperature }, + { SATURATION, &Saturation }, + { SENSOR_BLACK_LEVELS, &SensorBlackLevels }, + { SHARPNESS, &Sharpness }, + { FOCUS_FO_M, &FocusFoM }, + { COLOUR_CORRECTION_MATRIX, &ColourCorrectionMatrix }, + { SCALER_CROP, &ScalerCrop }, + { DIGITAL_GAIN, &DigitalGain }, + { FRAME_DURATION, &FrameDuration }, + { FRAME_DURATION_LIMITS, &FrameDurationLimits }, + { SENSOR_TEMPERATURE, &SensorTemperature }, + { SENSOR_TIMESTAMP, &SensorTimestamp }, + { AF_MODE, &AfMode }, + { AF_RANGE, &AfRange }, + { AF_SPEED, &AfSpeed }, + { AF_METERING, &AfMetering }, + { AF_WINDOWS, &AfWindows }, + { AF_TRIGGER, &AfTrigger }, + { AF_PAUSE, &AfPause }, + { LENS_POSITION, &LensPosition }, + { AF_STATE, &AfState }, + { AF_PAUSE_STATE, &AfPauseState }, + { HDR_MODE, &HdrMode }, + { HDR_CHANNEL, &HdrChannel }, + { GAMMA, &Gamma }, + { DEBUG_METADATA_ENABLE, &DebugMetadataEnable }, + { FRAME_WALL_CLOCK, &FrameWallClock }, + { WDR_MODE, &WdrMode }, + { WDR_STRENGTH, &WdrStrength }, + { WDR_MAX_BRIGHT_PIXELS, &WdrMaxBrightPixels }, + { LENS_DEWARP_ENABLE, &LensDewarpEnable }, + { LENS_SHADING_CORRECTION_ENABLE, &LensShadingCorrectionEnable }, + { HUE, &Hue }, + { draft::AE_PRECAPTURE_TRIGGER, &draft::AePrecaptureTrigger }, + { draft::NOISE_REDUCTION_MODE, &draft::NoiseReductionMode }, + { draft::COLOR_CORRECTION_ABERRATION_MODE, &draft::ColorCorrectionAberrationMode }, + { draft::AWB_STATE, &draft::AwbState }, + { draft::SENSOR_ROLLING_SHUTTER_SKEW, &draft::SensorRollingShutterSkew }, + { draft::LENS_SHADING_MAP_MODE, &draft::LensShadingMapMode }, + { draft::PIPELINE_DEPTH, &draft::PipelineDepth }, + { draft::MAX_LATENCY, &draft::MaxLatency }, + { draft::TEST_PATTERN_MODE, &draft::TestPatternMode }, + { draft::FACE_DETECT_MODE, &draft::FaceDetectMode }, + { draft::FACE_DETECT_FACE_RECTANGLES, &draft::FaceDetectFaceRectangles }, + { draft::FACE_DETECT_FACE_SCORES, &draft::FaceDetectFaceScores }, + { draft::FACE_DETECT_FACE_LANDMARKS, &draft::FaceDetectFaceLandmarks }, + { draft::FACE_DETECT_FACE_IDS, &draft::FaceDetectFaceIds }, + { rpi::STATS_OUTPUT_ENABLE, &rpi::StatsOutputEnable }, + { rpi::BCM2835_STATS_OUTPUT, &rpi::Bcm2835StatsOutput }, + { rpi::SCALER_CROPS, &rpi::ScalerCrops }, + { rpi::PISP_STATS_OUTPUT, &rpi::PispStatsOutput }, + { rpi::SYNC_MODE, &rpi::SyncMode }, + { rpi::SYNC_READY, &rpi::SyncReady }, + { rpi::SYNC_TIMER, &rpi::SyncTimer }, + { rpi::SYNC_FRAMES, &rpi::SyncFrames }, + { rpi::CNN_OUTPUT_TENSOR, &rpi::CnnOutputTensor }, + { rpi::CNN_OUTPUT_TENSOR_INFO, &rpi::CnnOutputTensorInfo }, + { rpi::CNN_ENABLE_INPUT_TENSOR, &rpi::CnnEnableInputTensor }, + { rpi::CNN_INPUT_TENSOR, &rpi::CnnInputTensor }, + { rpi::CNN_INPUT_TENSOR_INFO, &rpi::CnnInputTensorInfo }, + { rpi::CNN_KPI_INFO, &rpi::CnnKpiInfo }, +}; + +} /* namespace controls */ + +} /* namespace libcamera */ \ No newline at end of file diff --git a/meson_generated/src/libcamera/glsl_shaders.h b/meson_generated/src/libcamera/glsl_shaders.h new file mode 100644 index 00000000..351dd9e8 --- /dev/null +++ b/meson_generated/src/libcamera/glsl_shaders.h @@ -0,0 +1,1124 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* This file is auto-generated, do not edit! */ + +#pragma once + +/* + * List the names of the shaders at the top of + * header for readability's sake + * + * unsigned char bayer_1x_packed_frag; + * unsigned char bayer_unpacked_frag; + * unsigned char bayer_unpacked_vert; + * unsigned char identity_vert; +*/ +/* Hex encoded shader data */ +unsigned char const bayer_1x_packed_frag [] = { +0x2f, 0x2a, 0x20, 0x53, 0x50, 0x44, 0x58, 0x2d, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x2d, +0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x3a, 0x20, 0x42, 0x53, 0x44, 0x2d, +0x32, 0x2d, 0x43, 0x6c, 0x61, 0x75, 0x73, 0x65, 0x20, 0x2a, 0x2f, 0x0a, 0x2f, 0x2a, 0x0a, 0x20, +0x2a, 0x20, 0x42, 0x61, 0x73, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, +0x6f, 0x64, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, +0x6a, 0x67, 0x74, 0x2e, 0x61, 0x6b, 0x70, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x63, 0x6f, 0x6d, +0x2f, 0x70, 0x61, 0x70, 0x65, 0x72, 0x73, 0x2f, 0x4d, 0x63, 0x47, 0x75, 0x69, 0x72, 0x65, 0x30, +0x38, 0x2f, 0x0a, 0x20, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x45, 0x66, 0x66, 0x69, 0x63, 0x69, 0x65, +0x6e, 0x74, 0x2c, 0x20, 0x48, 0x69, 0x67, 0x68, 0x2d, 0x51, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, +0x20, 0x42, 0x61, 0x79, 0x65, 0x72, 0x20, 0x44, 0x65, 0x6d, 0x6f, 0x73, 0x61, 0x69, 0x63, 0x20, +0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x6e, 0x20, 0x47, 0x50, 0x55, +0x73, 0x0a, 0x20, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x4d, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x20, 0x4d, +0x63, 0x47, 0x75, 0x69, 0x72, 0x65, 0x0a, 0x20, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x54, 0x68, 0x69, +0x73, 0x20, 0x70, 0x61, 0x70, 0x65, 0x72, 0x20, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x73, 0x20, +0x69, 0x6e, 0x20, 0x69, 0x73, 0x73, 0x75, 0x65, 0x20, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x20, +0x31, 0x33, 0x2c, 0x20, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x34, 0x2e, 0x0a, 0x20, 0x2a, +0x20, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x20, 0x2a, 0x20, 0x43, 0x6f, +0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x38, +0x2c, 0x20, 0x4d, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x20, 0x4d, 0x63, 0x47, 0x75, 0x69, 0x72, 0x65, +0x2e, 0x20, 0x41, 0x6c, 0x6c, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x73, 0x20, 0x72, 0x65, 0x73, +0x65, 0x72, 0x76, 0x65, 0x64, 0x2e, 0x0a, 0x20, 0x2a, 0x0a, 0x20, 0x2a, 0x0a, 0x20, 0x2a, 0x20, +0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x4c, 0x69, 0x6e, 0x61, +0x72, 0x6f, 0x20, 0x4c, 0x74, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x31, 0x30, 0x2f, 0x31, 0x32, +0x2d, 0x62, 0x69, 0x74, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x20, 0x76, 0x73, 0x20, 0x38, +0x2d, 0x62, 0x69, 0x74, 0x20, 0x72, 0x61, 0x77, 0x20, 0x42, 0x61, 0x79, 0x65, 0x72, 0x20, 0x66, +0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2c, 0x0a, 0x20, 0x2a, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x66, 0x6f, +0x72, 0x20, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x20, 0x64, 0x65, 0x6d, 0x6f, 0x73, 0x61, +0x69, 0x63, 0x20, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x2e, 0x0a, 0x20, 0x2a, +0x20, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x43, 0x29, 0x20, 0x32, +0x30, 0x32, 0x30, 0x2c, 0x20, 0x4c, 0x69, 0x6e, 0x61, 0x72, 0x6f, 0x0a, 0x20, 0x2a, 0x0a, 0x20, +0x2a, 0x20, 0x62, 0x61, 0x79, 0x65, 0x72, 0x5f, 0x31, 0x78, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, +0x64, 0x2e, 0x66, 0x72, 0x61, 0x67, 0x20, 0x2d, 0x20, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, +0x74, 0x20, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x66, 0x6f, +0x72, 0x20, 0x72, 0x61, 0x77, 0x20, 0x42, 0x61, 0x79, 0x65, 0x72, 0x20, 0x31, 0x30, 0x2d, 0x62, +0x69, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x31, 0x32, 0x2d, 0x62, 0x69, 0x74, 0x0a, 0x20, 0x2a, +0x20, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x73, 0x0a, +0x20, 0x2a, 0x2f, 0x0a, 0x0a, 0x23, 0x69, 0x66, 0x64, 0x65, 0x66, 0x20, 0x47, 0x4c, 0x5f, 0x45, +0x53, 0x0a, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x69, 0x67, 0x68, +0x70, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3b, 0x0a, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x0a, +0x0a, 0x2f, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x54, 0x68, 0x65, 0x73, 0x65, 0x20, 0x63, 0x6f, 0x6e, +0x73, 0x74, 0x61, 0x6e, 0x74, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, +0x74, 0x6f, 0x20, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x79, +0x74, 0x65, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x74, +0x68, 0x65, 0x20, 0x48, 0x53, 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66, 0x0a, 0x20, 0x2a, +0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, +0x3a, 0x0a, 0x20, 0x2a, 0x20, 0x42, 0x50, 0x50, 0x20, 0x2d, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, +0x20, 0x70, 0x65, 0x72, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x2c, 0x0a, 0x20, 0x2a, 0x20, 0x54, +0x48, 0x52, 0x45, 0x53, 0x48, 0x4f, 0x4c, 0x44, 0x5f, 0x4c, 0x20, 0x3d, 0x20, 0x66, 0x72, 0x61, +0x63, 0x74, 0x28, 0x42, 0x50, 0x50, 0x29, 0x20, 0x2a, 0x20, 0x30, 0x2e, 0x35, 0x20, 0x2b, 0x20, +0x30, 0x2e, 0x30, 0x32, 0x0a, 0x20, 0x2a, 0x20, 0x54, 0x48, 0x52, 0x45, 0x53, 0x48, 0x4f, 0x4c, +0x44, 0x5f, 0x48, 0x20, 0x3d, 0x20, 0x31, 0x2e, 0x30, 0x20, 0x2d, 0x20, 0x66, 0x72, 0x61, 0x63, +0x74, 0x28, 0x42, 0x50, 0x50, 0x29, 0x20, 0x2a, 0x20, 0x31, 0x2e, 0x35, 0x20, 0x2b, 0x20, 0x30, +0x2e, 0x30, 0x32, 0x0a, 0x20, 0x2a, 0x20, 0x4c, 0x65, 0x74, 0x20, 0x58, 0x20, 0x69, 0x73, 0x20, +0x74, 0x68, 0x65, 0x20, 0x78, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, +0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x20, +0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x62, 0x79, 0x74, 0x65, +0x73, 0x20, 0x28, 0x73, 0x6f, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x20, +0x2a, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x69, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, +0x30, 0x20, 0x74, 0x6f, 0x20, 0x28, 0x73, 0x74, 0x72, 0x69, 0x64, 0x65, 0x5f, 0x2d, 0x31, 0x29, +0x29, 0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, +0x20, 0x6e, 0x65, 0x61, 0x72, 0x65, 0x73, 0x74, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x2e, 0x0a, +0x20, 0x2a, 0x20, 0x45, 0x2e, 0x67, 0x2e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x52, 0x41, 0x57, 0x31, +0x30, 0x50, 0x3a, 0x0a, 0x20, 0x2a, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, 0x2d, 0x0a, +0x20, 0x2a, 0x20, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x4e, 0x6f, 0x20, 0x20, 0x20, 0x20, +0x7c, 0x20, 0x20, 0x30, 0x20, 0x20, 0x20, 0x31, 0x20, 0x20, 0x20, 0x20, 0x32, 0x20, 0x20, 0x20, +0x33, 0x20, 0x20, 0x20, 0x7c, 0x20, 0x20, 0x34, 0x20, 0x20, 0x20, 0x35, 0x20, 0x20, 0x20, 0x20, +0x36, 0x20, 0x20, 0x20, 0x37, 0x20, 0x20, 0x20, 0x7c, 0x20, 0x2e, 0x2e, 0x2e, 0x0a, 0x20, 0x2a, +0x20, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, +0x2d, 0x2d, 0x2b, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, 0x2d, 0x0a, 0x20, 0x2a, 0x20, 0x20, 0x62, 0x79, +0x74, 0x65, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x20, 0x7c, 0x20, 0x30, 0x20, 0x20, 0x20, +0x31, 0x20, 0x20, 0x20, 0x32, 0x20, 0x20, 0x20, 0x33, 0x20, 0x20, 0x20, 0x34, 0x20, 0x7c, 0x20, +0x35, 0x20, 0x20, 0x20, 0x36, 0x20, 0x20, 0x20, 0x37, 0x20, 0x20, 0x20, 0x38, 0x20, 0x20, 0x20, +0x39, 0x20, 0x7c, 0x20, 0x2e, 0x2e, 0x2e, 0x0a, 0x20, 0x2a, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, 0x2d, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, +0x2b, 0x2d, 0x2d, 0x0a, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x7c, 0x20, 0x30, 0x2e, 0x30, 0x20, 0x31, 0x2e, 0x32, 0x35, 0x20, 0x32, +0x2e, 0x35, 0x20, 0x33, 0x2e, 0x37, 0x35, 0x20, 0x7c, 0x20, 0x35, 0x2e, 0x30, 0x20, 0x36, 0x2e, +0x32, 0x35, 0x20, 0x37, 0x2e, 0x35, 0x20, 0x38, 0x2e, 0x37, 0x35, 0x20, 0x7c, 0x20, 0x2e, 0x2e, +0x2e, 0x0a, 0x20, 0x2a, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, +0x2d, 0x2d, 0x2b, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, 0x2d, 0x0a, 0x20, 0x2a, +0x20, 0x49, 0x66, 0x20, 0x66, 0x72, 0x61, 0x63, 0x74, 0x28, 0x58, 0x29, 0x20, 0x3c, 0x20, 0x54, +0x48, 0x52, 0x45, 0x53, 0x48, 0x4f, 0x4c, 0x44, 0x5f, 0x4c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, +0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x20, 0x62, 0x79, 0x74, +0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4c, +0x53, 0x0a, 0x20, 0x2a, 0x20, 0x62, 0x69, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, +0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x61, 0x6e, +0x64, 0x20, 0x6e, 0x65, 0x65, 0x64, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x73, 0x6b, +0x69, 0x70, 0x70, 0x65, 0x64, 0x2e, 0x0a, 0x20, 0x2a, 0x20, 0x49, 0x66, 0x20, 0x66, 0x72, 0x61, +0x63, 0x74, 0x28, 0x58, 0x29, 0x20, 0x3e, 0x20, 0x54, 0x48, 0x52, 0x45, 0x53, 0x48, 0x4f, 0x4c, +0x44, 0x5f, 0x48, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x65, 0x78, +0x74, 0x20, 0x62, 0x79, 0x74, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x20, +0x74, 0x68, 0x65, 0x20, 0x4c, 0x53, 0x20, 0x62, 0x69, 0x74, 0x73, 0x0a, 0x20, 0x2a, 0x20, 0x6f, +0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x76, 0x61, 0x6c, 0x75, +0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x65, 0x65, 0x64, 0x73, 0x20, 0x74, 0x6f, 0x20, +0x62, 0x65, 0x20, 0x73, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x2e, 0x0a, 0x20, 0x2a, 0x2f, 0x0a, +0x23, 0x69, 0x66, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x28, 0x52, 0x41, 0x57, 0x31, +0x30, 0x50, 0x29, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x42, 0x50, 0x50, 0x09, +0x09, 0x31, 0x2e, 0x32, 0x35, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x54, 0x48, +0x52, 0x45, 0x53, 0x48, 0x4f, 0x4c, 0x44, 0x5f, 0x4c, 0x09, 0x30, 0x2e, 0x31, 0x34, 0x0a, 0x23, +0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x54, 0x48, 0x52, 0x45, 0x53, 0x48, 0x4f, 0x4c, 0x44, +0x5f, 0x48, 0x09, 0x30, 0x2e, 0x36, 0x34, 0x0a, 0x23, 0x65, 0x6c, 0x69, 0x66, 0x20, 0x64, 0x65, +0x66, 0x69, 0x6e, 0x65, 0x64, 0x28, 0x52, 0x41, 0x57, 0x31, 0x32, 0x50, 0x29, 0x0a, 0x23, 0x64, +0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x42, 0x50, 0x50, 0x09, 0x09, 0x31, 0x2e, 0x35, 0x0a, 0x23, +0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x54, 0x48, 0x52, 0x45, 0x53, 0x48, 0x4f, 0x4c, 0x44, +0x5f, 0x4c, 0x09, 0x30, 0x2e, 0x32, 0x37, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, +0x54, 0x48, 0x52, 0x45, 0x53, 0x48, 0x4f, 0x4c, 0x44, 0x5f, 0x48, 0x09, 0x30, 0x2e, 0x32, 0x37, +0x0a, 0x23, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x23, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x49, 0x6e, +0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x72, 0x61, 0x77, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, +0x0a, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x0a, 0x0a, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, +0x67, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x4f, 0x75, +0x74, 0x3b, 0x0a, 0x0a, 0x2f, 0x2a, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, +0x72, 0x65, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, +0x73, 0x20, 0x2a, 0x2f, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x76, 0x65, 0x63, +0x32, 0x20, 0x74, 0x65, 0x78, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, +0x6f, 0x72, 0x6d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, 0x65, 0x78, 0x5f, 0x73, 0x74, 0x65, +0x70, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, +0x74, 0x65, 0x78, 0x5f, 0x62, 0x61, 0x79, 0x65, 0x72, 0x5f, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, +0x72, 0x65, 0x64, 0x3b, 0x0a, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, +0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x74, 0x65, 0x78, 0x5f, 0x79, 0x3b, 0x0a, 0x75, +0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6d, 0x61, 0x74, 0x33, 0x20, 0x63, 0x63, 0x6d, 0x3b, +0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20, 0x62, 0x6c, +0x61, 0x63, 0x6b, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, +0x6d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x67, 0x61, 0x6d, 0x6d, 0x61, 0x3b, 0x0a, 0x75, +0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x63, 0x6f, 0x6e, +0x74, 0x72, 0x61, 0x73, 0x74, 0x45, 0x78, 0x70, 0x3b, 0x0a, 0x0a, 0x66, 0x6c, 0x6f, 0x61, 0x74, +0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x73, 0x74, 0x28, +0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x29, 0x0a, 0x7b, 0x0a, 0x09, +0x2f, 0x2f, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x20, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, +0x53, 0x2d, 0x63, 0x75, 0x72, 0x76, 0x65, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x28, 0x76, 0x61, 0x6c, +0x75, 0x65, 0x20, 0x3c, 0x20, 0x30, 0x2e, 0x35, 0x29, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, +0x72, 0x6e, 0x20, 0x30, 0x2e, 0x35, 0x20, 0x2a, 0x20, 0x70, 0x6f, 0x77, 0x28, 0x76, 0x61, 0x6c, +0x75, 0x65, 0x20, 0x2f, 0x20, 0x30, 0x2e, 0x35, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, +0x73, 0x74, 0x45, 0x78, 0x70, 0x29, 0x3b, 0x0a, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, +0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, 0x2e, 0x30, 0x20, 0x2d, 0x20, 0x30, 0x2e, 0x35, +0x20, 0x2a, 0x20, 0x70, 0x6f, 0x77, 0x28, 0x28, 0x31, 0x2e, 0x30, 0x20, 0x2d, 0x20, 0x76, 0x61, +0x6c, 0x75, 0x65, 0x29, 0x20, 0x2f, 0x20, 0x30, 0x2e, 0x35, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x74, +0x72, 0x61, 0x73, 0x74, 0x45, 0x78, 0x70, 0x29, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x76, 0x6f, 0x69, +0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x76, 0x6f, 0x69, 0x64, 0x29, 0x0a, 0x7b, 0x0a, 0x09, +0x76, 0x65, 0x63, 0x33, 0x20, 0x72, 0x67, 0x62, 0x3b, 0x0a, 0x0a, 0x09, 0x2f, 0x2a, 0x0a, 0x09, +0x20, 0x2a, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x20, +0x68, 0x6f, 0x6c, 0x64, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, +0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4d, 0x53, 0x20, +0x62, 0x79, 0x74, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x69, 0x78, 0x65, +0x6c, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x62, 0x65, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x61, 0x6d, 0x70, +0x6c, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x5b, 0x30, 0x2c, 0x20, 0x73, +0x74, 0x72, 0x69, 0x64, 0x65, 0x2d, 0x31, 0x2f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x2d, 0x31, +0x5d, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x63, 0x65, 0x6e, +0x74, 0x65, 0x72, 0x5f, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x68, 0x6f, 0x6c, 0x64, 0x73, 0x20, +0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, +0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x62, 0x65, 0x69, +0x6e, 0x67, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x64, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x6f, +0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x5b, 0x30, 0x2c, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x2f, +0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x2d, 0x31, 0x5d, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x2e, +0x0a, 0x09, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x76, 0x65, 0x63, 0x32, 0x20, 0x63, 0x65, 0x6e, 0x74, +0x65, 0x72, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x3b, 0x0a, 0x09, 0x76, 0x65, 0x63, 0x32, 0x20, +0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x3b, 0x0a, 0x0a, 0x09, +0x2f, 0x2a, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x78, 0x2d, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x79, 0x2d, +0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, +0x20, 0x61, 0x64, 0x6a, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x73, +0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x5b, 0x30, 0x2c, 0x20, 0x31, 0x5d, 0x20, 0x72, +0x61, 0x6e, 0x67, 0x65, 0x2e, 0x0a, 0x09, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x76, 0x65, 0x63, 0x32, +0x20, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x73, 0x3b, 0x0a, 0x09, 0x76, 0x65, 0x63, 0x32, 0x20, +0x79, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x73, 0x3b, 0x0a, 0x0a, 0x09, 0x2f, 0x2a, 0x0a, 0x09, 0x20, +0x2a, 0x20, 0x54, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, +0x73, 0x20, 0x70, 0x61, 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, +0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, +0x65, 0x4f, 0x75, 0x74, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x0a, 0x09, +0x20, 0x2a, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x20, 0x69, 0x6e, +0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x69, 0x78, +0x65, 0x6c, 0x73, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, +0x72, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x65, 0x73, 0x6e, 0x27, +0x74, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, +0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x20, 0x49, 0x6e, +0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, 0x6c, 0x61, 0x72, 0x2c, 0x20, 0x4d, 0x49, 0x50, +0x49, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x20, 0x72, 0x61, 0x77, 0x20, 0x42, 0x61, 0x79, +0x65, 0x72, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x73, 0x20, 0x64, +0x6f, 0x6e, 0x27, 0x74, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x61, 0x20, 0x6d, 0x61, 0x74, 0x63, +0x68, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x20, 0x66, 0x6f, 0x72, +0x6d, 0x61, 0x74, 0x2e, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x49, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, +0x20, 0x63, 0x61, 0x73, 0x65, 0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, +0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x74, +0x68, 0x65, 0x20, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x6e, 0x65, 0x61, 0x72, 0x65, 0x73, 0x74, 0x20, +0x70, 0x69, 0x78, 0x65, 0x6c, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x62, 0x79, 0x20, 0x68, 0x61, 0x6e, +0x64, 0x2e, 0x0a, 0x09, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x5f, +0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x3d, 0x20, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x74, 0x65, +0x78, 0x74, 0x75, 0x72, 0x65, 0x4f, 0x75, 0x74, 0x20, 0x2a, 0x20, 0x74, 0x65, 0x78, 0x5f, 0x73, +0x69, 0x7a, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x62, 0x79, +0x74, 0x65, 0x73, 0x2e, 0x79, 0x20, 0x3d, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x70, +0x69, 0x78, 0x65, 0x6c, 0x2e, 0x79, 0x3b, 0x0a, 0x0a, 0x09, 0x2f, 0x2a, 0x0a, 0x09, 0x20, 0x2a, +0x20, 0x41, 0x64, 0x64, 0x20, 0x61, 0x20, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x20, 0x6e, 0x75, 0x6d, +0x62, 0x65, 0x72, 0x20, 0x28, 0x61, 0x20, 0x66, 0x65, 0x77, 0x20, 0x6d, 0x61, 0x6e, 0x74, 0x69, +0x73, 0x73, 0x61, 0x27, 0x73, 0x20, 0x4c, 0x53, 0x42, 0x73, 0x29, 0x20, 0x74, 0x6f, 0x20, 0x61, +0x76, 0x6f, 0x69, 0x64, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x72, +0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, +0x73, 0x75, 0x65, 0x73, 0x2e, 0x20, 0x4d, 0x61, 0x79, 0x62, 0x65, 0x20, 0x70, 0x61, 0x72, 0x61, +0x6e, 0x6f, 0x69, 0x63, 0x2e, 0x0a, 0x09, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x63, 0x65, 0x6e, 0x74, +0x65, 0x72, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, 0x78, 0x20, 0x3d, 0x20, 0x42, 0x50, 0x50, +0x20, 0x2a, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x2e, +0x78, 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x30, 0x32, 0x3b, 0x0a, 0x0a, 0x09, 0x66, 0x6c, 0x6f, 0x61, +0x74, 0x20, 0x66, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x78, 0x20, 0x3d, 0x20, 0x66, 0x72, 0x61, 0x63, +0x74, 0x28, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, 0x78, +0x29, 0x3b, 0x0a, 0x0a, 0x09, 0x2f, 0x2a, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x54, 0x68, 0x65, 0x20, +0x62, 0x65, 0x6c, 0x6f, 0x77, 0x20, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x29, 0x20, 0x63, 0x61, +0x6c, 0x6c, 0x20, 0x65, 0x6e, 0x73, 0x75, 0x72, 0x65, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, +0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, 0x78, 0x20, 0x70, +0x6f, 0x69, 0x6e, 0x74, 0x73, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x61, 0x74, 0x20, 0x6f, 0x6e, 0x65, +0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x20, 0x72, 0x65, +0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x38, +0x20, 0x68, 0x69, 0x67, 0x68, 0x65, 0x72, 0x20, 0x62, 0x69, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x0a, +0x09, 0x20, 0x2a, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x76, 0x61, +0x6c, 0x75, 0x65, 0x2c, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, +0x62, 0x79, 0x74, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x20, +0x74, 0x68, 0x65, 0x20, 0x4c, 0x53, 0x20, 0x62, 0x69, 0x74, 0x73, 0x0a, 0x09, 0x20, 0x2a, 0x20, +0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x6f, 0x66, 0x20, +0x74, 0x68, 0x65, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x73, 0x2e, 0x0a, 0x09, 0x20, 0x2a, 0x2f, +0x0a, 0x09, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, 0x78, +0x20, 0x3d, 0x20, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x5f, +0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, 0x78, 0x29, 0x3b, 0x0a, 0x09, 0x63, 0x65, 0x6e, 0x74, 0x65, +0x72, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x20, 0x2a, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x5f, 0x73, +0x74, 0x65, 0x70, 0x3b, 0x0a, 0x0a, 0x09, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x73, 0x20, 0x3d, +0x20, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, 0x78, 0x20, +0x2b, 0x20, 0x76, 0x65, 0x63, 0x32, 0x28, 0x2d, 0x74, 0x65, 0x78, 0x5f, 0x73, 0x74, 0x65, 0x70, +0x2e, 0x78, 0x2c, 0x20, 0x74, 0x65, 0x78, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x2e, 0x78, 0x29, 0x3b, +0x0a, 0x09, 0x79, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x73, 0x20, 0x3d, 0x20, 0x63, 0x65, 0x6e, 0x74, +0x65, 0x72, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, 0x79, 0x20, 0x2b, 0x20, 0x76, 0x65, 0x63, +0x32, 0x28, 0x2d, 0x74, 0x65, 0x78, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x2e, 0x79, 0x2c, 0x20, 0x74, +0x65, 0x78, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x2e, 0x79, 0x29, 0x3b, 0x0a, 0x0a, 0x09, 0x2f, 0x2a, +0x0a, 0x09, 0x20, 0x2a, 0x20, 0x49, 0x66, 0x20, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x73, 0x5b, +0x30, 0x5d, 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x20, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, +0x20, 0x62, 0x79, 0x74, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, +0x20, 0x74, 0x68, 0x65, 0x20, 0x4c, 0x53, 0x20, 0x62, 0x69, 0x74, 0x73, 0x0a, 0x09, 0x20, 0x2a, +0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, +0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x69, +0x78, 0x65, 0x6c, 0x73, 0x2c, 0x20, 0x6d, 0x6f, 0x76, 0x65, 0x20, 0x78, 0x63, 0x6f, 0x6f, 0x72, +0x64, 0x73, 0x5b, 0x30, 0x5d, 0x20, 0x6f, 0x6e, 0x65, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x62, 0x79, +0x74, 0x65, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x0a, 0x09, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x78, +0x63, 0x6f, 0x6f, 0x72, 0x64, 0x73, 0x5b, 0x30, 0x5d, 0x20, 0x2b, 0x3d, 0x20, 0x28, 0x66, 0x72, +0x61, 0x63, 0x74, 0x5f, 0x78, 0x20, 0x3c, 0x20, 0x54, 0x48, 0x52, 0x45, 0x53, 0x48, 0x4f, 0x4c, +0x44, 0x5f, 0x4c, 0x29, 0x20, 0x3f, 0x20, 0x2d, 0x74, 0x65, 0x78, 0x5f, 0x73, 0x74, 0x65, 0x70, +0x2e, 0x78, 0x20, 0x3a, 0x20, 0x30, 0x2e, 0x30, 0x3b, 0x0a, 0x0a, 0x09, 0x2f, 0x2a, 0x0a, 0x09, +0x20, 0x2a, 0x20, 0x49, 0x66, 0x20, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x73, 0x5b, 0x31, 0x5d, +0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x20, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, +0x79, 0x74, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x74, +0x68, 0x65, 0x20, 0x4c, 0x53, 0x20, 0x62, 0x69, 0x74, 0x73, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x6f, +0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x67, 0x72, +0x6f, 0x75, 0x70, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, +0x73, 0x2c, 0x20, 0x6d, 0x6f, 0x76, 0x65, 0x20, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x73, 0x5b, +0x31, 0x5d, 0x20, 0x6f, 0x6e, 0x65, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x62, 0x79, 0x74, 0x65, 0x20, +0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x2e, 0x0a, 0x09, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x78, +0x63, 0x6f, 0x6f, 0x72, 0x64, 0x73, 0x5b, 0x31, 0x5d, 0x20, 0x2b, 0x3d, 0x20, 0x28, 0x66, 0x72, +0x61, 0x63, 0x74, 0x5f, 0x78, 0x20, 0x3e, 0x20, 0x54, 0x48, 0x52, 0x45, 0x53, 0x48, 0x4f, 0x4c, +0x44, 0x5f, 0x48, 0x29, 0x20, 0x3f, 0x20, 0x74, 0x65, 0x78, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x2e, +0x78, 0x20, 0x3a, 0x20, 0x30, 0x2e, 0x30, 0x3b, 0x0a, 0x0a, 0x09, 0x76, 0x65, 0x63, 0x32, 0x20, +0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x3d, 0x20, 0x6d, 0x6f, 0x64, 0x28, +0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x2e, 0x78, 0x79, 0x20, +0x2b, 0x20, 0x74, 0x65, 0x78, 0x5f, 0x62, 0x61, 0x79, 0x65, 0x72, 0x5f, 0x66, 0x69, 0x72, 0x73, +0x74, 0x5f, 0x72, 0x65, 0x64, 0x2c, 0x20, 0x32, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x09, 0x62, 0x6f, +0x6f, 0x6c, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x5f, 0x63, 0x6f, 0x6c, 0x20, 0x3d, 0x20, 0x61, 0x6c, +0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x2e, 0x78, 0x20, 0x3c, 0x20, 0x31, 0x2e, 0x30, 0x3b, +0x0a, 0x09, 0x62, 0x6f, 0x6f, 0x6c, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x5f, 0x72, 0x6f, 0x77, 0x20, +0x3d, 0x20, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x2e, 0x79, 0x20, 0x3c, 0x20, +0x31, 0x2e, 0x30, 0x3b, 0x0a, 0x0a, 0x09, 0x2f, 0x2a, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x57, 0x65, +0x20, 0x6e, 0x65, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, +0x74, 0x68, 0x65, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x70, 0x69, 0x78, 0x65, +0x6c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x6e, 0x65, 0x73, 0x20, 0x77, +0x69, 0x74, 0x68, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x6f, +0x66, 0x20, 0x2d, 0x31, 0x20, 0x74, 0x6f, 0x20, 0x2b, 0x31, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, +0x20, 0x69, 0x6e, 0x20, 0x62, 0x6f, 0x74, 0x68, 0x20, 0x58, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x59, +0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x20, 0x4c, 0x65, 0x74, +0x27, 0x73, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x74, 0x68, 0x65, 0x73, 0x65, 0x0a, 0x09, 0x20, +0x2a, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x73, 0x20, 0x61, 0x73, 0x20, 0x62, 0x65, 0x6c, 0x6f, +0x77, 0x2c, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x43, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, +0x65, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x3a, +0x0a, 0x09, 0x20, 0x2a, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x2b, 0x2d, 0x2d, 0x2d, 0x2d, +0x2b, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, +0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x7c, 0x20, 0x5c, 0x20, 0x78, 0x7c, 0x20, 0x20, 0x20, +0x20, 0x7c, 0x20, 0x20, 0x20, 0x20, 0x7c, 0x20, 0x20, 0x20, 0x20, 0x7c, 0x0a, 0x09, 0x20, 0x2a, +0x20, 0x20, 0x20, 0x7c, 0x79, 0x20, 0x5c, 0x20, 0x7c, 0x20, 0x2d, 0x31, 0x20, 0x7c, 0x20, 0x20, +0x30, 0x20, 0x7c, 0x20, 0x2b, 0x31, 0x20, 0x7c, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x2b, +0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, +0x2d, 0x2d, 0x2d, 0x2b, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x7c, 0x20, 0x2b, 0x31, 0x20, +0x7c, 0x20, 0x44, 0x32, 0x20, 0x7c, 0x20, 0x41, 0x31, 0x20, 0x7c, 0x20, 0x44, 0x33, 0x20, 0x7c, +0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x2b, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, 0x2d, 0x2d, +0x2d, 0x2b, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x0a, 0x09, 0x20, 0x2a, +0x20, 0x20, 0x20, 0x7c, 0x20, 0x20, 0x30, 0x20, 0x7c, 0x20, 0x42, 0x30, 0x20, 0x7c, 0x20, 0x20, +0x43, 0x20, 0x7c, 0x20, 0x42, 0x31, 0x20, 0x7c, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x2b, +0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, +0x2d, 0x2d, 0x2d, 0x2b, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x7c, 0x20, 0x2d, 0x31, 0x20, +0x7c, 0x20, 0x44, 0x30, 0x20, 0x7c, 0x20, 0x41, 0x30, 0x20, 0x7c, 0x20, 0x44, 0x31, 0x20, 0x7c, +0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x2b, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, 0x2d, 0x2d, +0x2d, 0x2b, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x0a, 0x09, 0x20, 0x2a, +0x0a, 0x09, 0x20, 0x2a, 0x20, 0x49, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x65, 0x6c, 0x6f, +0x77, 0x20, 0x65, 0x71, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x28, 0x30, 0x2c, 0x2d, +0x31, 0x29, 0x2e, 0x72, 0x20, 0x6d, 0x65, 0x61, 0x6e, 0x73, 0x20, 0x22, 0x72, 0x20, 0x63, 0x6f, +0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, +0x65, 0x78, 0x65, 0x6c, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x73, 0x68, 0x69, 0x66, 0x74, 0x65, 0x64, +0x20, 0x62, 0x79, 0x20, 0x2d, 0x74, 0x65, 0x78, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x2e, 0x79, 0x20, +0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x5f, +0x62, 0x79, 0x74, 0x65, 0x73, 0x20, 0x6f, 0x6e, 0x65, 0x22, 0x20, 0x65, 0x74, 0x63, 0x2e, 0x0a, +0x09, 0x20, 0x2a, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x49, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, +0x76, 0x65, 0x6e, 0x20, 0x72, 0x6f, 0x77, 0x20, 0x2f, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x20, 0x63, +0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x20, 0x28, 0x45, 0x45, 0x29, 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, +0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, +0x73, 0x20, 0x61, 0x72, 0x65, 0x3a, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x52, 0x20, 0x3d, +0x20, 0x43, 0x20, 0x3d, 0x20, 0x28, 0x30, 0x2c, 0x30, 0x29, 0x2e, 0x72, 0x2c, 0x0a, 0x09, 0x20, +0x2a, 0x20, 0x20, 0x20, 0x47, 0x20, 0x3d, 0x20, 0x28, 0x41, 0x30, 0x20, 0x2b, 0x20, 0x41, 0x31, +0x20, 0x2b, 0x20, 0x42, 0x30, 0x20, 0x2b, 0x20, 0x42, 0x31, 0x29, 0x20, 0x2f, 0x20, 0x34, 0x2e, +0x30, 0x20, 0x3d, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x20, +0x28, 0x30, 0x2c, 0x2d, 0x31, 0x29, 0x2e, 0x72, 0x20, 0x2b, 0x20, 0x28, 0x30, 0x2c, 0x31, 0x29, +0x2e, 0x72, 0x20, 0x2b, 0x20, 0x28, 0x2d, 0x31, 0x2c, 0x30, 0x29, 0x2e, 0x72, 0x20, 0x2b, 0x20, +0x28, 0x31, 0x2c, 0x30, 0x29, 0x2e, 0x72, 0x20, 0x29, 0x20, 0x2f, 0x20, 0x34, 0x2e, 0x30, 0x2c, +0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x42, 0x20, 0x3d, 0x20, 0x28, 0x44, 0x30, 0x20, 0x2b, +0x20, 0x44, 0x31, 0x20, 0x2b, 0x20, 0x44, 0x32, 0x20, 0x2b, 0x20, 0x44, 0x33, 0x29, 0x20, 0x2f, +0x20, 0x34, 0x2e, 0x30, 0x20, 0x3d, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x28, 0x20, 0x28, 0x2d, 0x31, 0x2c, 0x2d, 0x31, 0x29, 0x2e, 0x72, 0x20, 0x2b, 0x20, 0x28, +0x31, 0x2c, 0x2d, 0x31, 0x29, 0x2e, 0x72, 0x20, 0x2b, 0x20, 0x28, 0x2d, 0x31, 0x2c, 0x31, 0x29, +0x2e, 0x72, 0x20, 0x2b, 0x20, 0x28, 0x31, 0x2c, 0x31, 0x29, 0x2e, 0x72, 0x20, 0x29, 0x20, 0x2f, +0x20, 0x34, 0x2e, 0x30, 0x0a, 0x09, 0x20, 0x2a, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x46, 0x6f, 0x72, +0x20, 0x65, 0x76, 0x65, 0x6e, 0x20, 0x72, 0x6f, 0x77, 0x20, 0x2f, 0x20, 0x6f, 0x64, 0x64, 0x20, +0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x20, 0x28, 0x45, 0x4f, 0x29, 0x3a, 0x0a, 0x09, 0x20, 0x2a, +0x20, 0x20, 0x20, 0x52, 0x20, 0x3d, 0x20, 0x28, 0x42, 0x30, 0x20, 0x2b, 0x20, 0x42, 0x31, 0x29, +0x20, 0x2f, 0x20, 0x32, 0x2e, 0x30, 0x20, 0x3d, 0x20, 0x28, 0x20, 0x28, 0x2d, 0x31, 0x2c, 0x30, +0x29, 0x2e, 0x72, 0x20, 0x2b, 0x20, 0x28, 0x31, 0x2c, 0x30, 0x29, 0x2e, 0x72, 0x20, 0x29, 0x20, +0x2f, 0x20, 0x32, 0x2e, 0x30, 0x2c, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x47, 0x20, 0x3d, +0x20, 0x43, 0x20, 0x3d, 0x20, 0x28, 0x30, 0x2c, 0x30, 0x29, 0x2e, 0x72, 0x2c, 0x0a, 0x09, 0x20, +0x2a, 0x20, 0x20, 0x20, 0x42, 0x20, 0x3d, 0x20, 0x28, 0x41, 0x30, 0x20, 0x2b, 0x20, 0x41, 0x31, +0x29, 0x20, 0x2f, 0x20, 0x32, 0x2e, 0x30, 0x20, 0x3d, 0x20, 0x28, 0x20, 0x28, 0x30, 0x2c, 0x2d, +0x31, 0x29, 0x2e, 0x72, 0x20, 0x2b, 0x20, 0x28, 0x30, 0x2c, 0x31, 0x29, 0x2e, 0x72, 0x20, 0x29, +0x20, 0x2f, 0x20, 0x32, 0x2e, 0x30, 0x0a, 0x09, 0x20, 0x2a, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x46, +0x6f, 0x72, 0x20, 0x6f, 0x64, 0x64, 0x20, 0x72, 0x6f, 0x77, 0x20, 0x2f, 0x20, 0x65, 0x76, 0x65, +0x6e, 0x20, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x20, 0x28, 0x4f, 0x45, 0x29, 0x3a, 0x0a, 0x09, +0x20, 0x2a, 0x20, 0x20, 0x20, 0x52, 0x20, 0x3d, 0x20, 0x28, 0x41, 0x30, 0x20, 0x2b, 0x20, 0x41, +0x31, 0x29, 0x20, 0x2f, 0x20, 0x32, 0x2e, 0x30, 0x20, 0x3d, 0x20, 0x28, 0x20, 0x28, 0x30, 0x2c, +0x2d, 0x31, 0x29, 0x2e, 0x72, 0x20, 0x2b, 0x20, 0x28, 0x30, 0x2c, 0x31, 0x29, 0x2e, 0x72, 0x20, +0x29, 0x20, 0x2f, 0x20, 0x32, 0x2e, 0x30, 0x2c, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x47, +0x20, 0x3d, 0x20, 0x43, 0x20, 0x3d, 0x20, 0x28, 0x30, 0x2c, 0x30, 0x29, 0x2e, 0x72, 0x2c, 0x0a, +0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x42, 0x20, 0x3d, 0x20, 0x28, 0x42, 0x30, 0x20, 0x2b, 0x20, +0x42, 0x31, 0x29, 0x20, 0x2f, 0x20, 0x32, 0x2e, 0x30, 0x20, 0x3d, 0x20, 0x28, 0x20, 0x28, 0x2d, +0x31, 0x2c, 0x30, 0x29, 0x2e, 0x72, 0x20, 0x2b, 0x20, 0x28, 0x31, 0x2c, 0x30, 0x29, 0x2e, 0x72, +0x20, 0x29, 0x20, 0x2f, 0x20, 0x32, 0x2e, 0x30, 0x0a, 0x09, 0x20, 0x2a, 0x0a, 0x09, 0x20, 0x2a, +0x20, 0x46, 0x6f, 0x72, 0x20, 0x6f, 0x64, 0x64, 0x20, 0x72, 0x6f, 0x77, 0x20, 0x2f, 0x20, 0x6f, +0x64, 0x64, 0x20, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x20, 0x28, 0x4f, 0x4f, 0x29, 0x3a, 0x0a, +0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x52, 0x20, 0x3d, 0x20, 0x28, 0x44, 0x30, 0x20, 0x2b, 0x20, +0x44, 0x31, 0x20, 0x2b, 0x20, 0x44, 0x32, 0x20, 0x2b, 0x20, 0x44, 0x33, 0x29, 0x20, 0x2f, 0x20, +0x34, 0x2e, 0x30, 0x20, 0x3d, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x28, 0x20, 0x28, 0x2d, 0x31, 0x2c, 0x2d, 0x31, 0x29, 0x2e, 0x72, 0x20, 0x2b, 0x20, 0x28, 0x31, +0x2c, 0x2d, 0x31, 0x29, 0x2e, 0x72, 0x20, 0x2b, 0x20, 0x28, 0x2d, 0x31, 0x2c, 0x31, 0x29, 0x2e, +0x72, 0x20, 0x2b, 0x20, 0x28, 0x31, 0x2c, 0x31, 0x29, 0x2e, 0x72, 0x20, 0x29, 0x20, 0x2f, 0x20, +0x34, 0x2e, 0x30, 0x2c, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x47, 0x20, 0x3d, 0x20, 0x28, +0x41, 0x30, 0x20, 0x2b, 0x20, 0x41, 0x31, 0x20, 0x2b, 0x20, 0x42, 0x30, 0x20, 0x2b, 0x20, 0x42, +0x31, 0x29, 0x20, 0x2f, 0x20, 0x34, 0x2e, 0x30, 0x20, 0x3d, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x20, 0x28, 0x30, 0x2c, 0x2d, 0x31, 0x29, 0x2e, 0x72, 0x20, +0x2b, 0x20, 0x28, 0x30, 0x2c, 0x31, 0x29, 0x2e, 0x72, 0x20, 0x2b, 0x20, 0x28, 0x2d, 0x31, 0x2c, +0x30, 0x29, 0x2e, 0x72, 0x20, 0x2b, 0x20, 0x28, 0x31, 0x2c, 0x30, 0x29, 0x2e, 0x72, 0x20, 0x29, +0x20, 0x2f, 0x20, 0x34, 0x2e, 0x30, 0x2c, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x42, 0x20, +0x3d, 0x20, 0x43, 0x20, 0x3d, 0x20, 0x28, 0x30, 0x2c, 0x30, 0x29, 0x2e, 0x72, 0x0a, 0x09, 0x20, +0x2a, 0x2f, 0x0a, 0x0a, 0x09, 0x2f, 0x2a, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x46, 0x65, 0x74, 0x63, +0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, +0x20, 0x70, 0x72, 0x65, 0x63, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x20, 0x74, 0x68, +0x65, 0x20, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x3a, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x70, +0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x73, 0x2e, 0x78, 0x20, 0x3d, 0x20, 0x28, 0x41, 0x30, 0x20, +0x2b, 0x20, 0x41, 0x31, 0x29, 0x20, 0x2f, 0x20, 0x32, 0x2e, 0x30, 0x0a, 0x09, 0x20, 0x2a, 0x20, +0x20, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x73, 0x2e, 0x79, 0x20, 0x3d, 0x20, 0x28, +0x42, 0x30, 0x20, 0x2b, 0x20, 0x42, 0x31, 0x29, 0x20, 0x2f, 0x20, 0x32, 0x2e, 0x30, 0x0a, 0x09, +0x20, 0x2a, 0x20, 0x20, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x73, 0x2e, 0x7a, 0x20, +0x3d, 0x20, 0x28, 0x41, 0x30, 0x20, 0x2b, 0x20, 0x41, 0x31, 0x20, 0x2b, 0x20, 0x42, 0x30, 0x20, +0x2b, 0x20, 0x42, 0x31, 0x29, 0x20, 0x2f, 0x20, 0x34, 0x2e, 0x30, 0x0a, 0x09, 0x20, 0x2a, 0x20, +0x20, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x73, 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x28, +0x44, 0x30, 0x20, 0x2b, 0x20, 0x44, 0x31, 0x20, 0x2b, 0x20, 0x44, 0x32, 0x20, 0x2b, 0x20, 0x44, +0x33, 0x29, 0x20, 0x2f, 0x20, 0x34, 0x2e, 0x30, 0x0a, 0x09, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x23, +0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x78, 0x2c, 0x20, +0x79, 0x29, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x28, 0x74, 0x65, 0x78, +0x5f, 0x79, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x32, 0x28, 0x78, 0x2c, 0x20, 0x79, 0x29, 0x29, 0x2e, +0x72, 0x0a, 0x0a, 0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x43, 0x20, 0x3d, 0x20, 0x74, 0x65, +0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x28, 0x74, 0x65, 0x78, 0x5f, 0x79, 0x2c, 0x20, 0x63, +0x65, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x29, 0x2e, 0x72, 0x3b, 0x0a, +0x09, 0x76, 0x65, 0x63, 0x34, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x73, 0x20, 0x3d, +0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x0a, 0x09, 0x09, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x63, +0x65, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, 0x78, 0x2c, 0x20, 0x79, +0x63, 0x6f, 0x6f, 0x72, 0x64, 0x73, 0x5b, 0x30, 0x5d, 0x29, 0x2c, 0x09, 0x2f, 0x2a, 0x20, 0x41, +0x30, 0x3a, 0x20, 0x28, 0x30, 0x2c, 0x2d, 0x31, 0x29, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x09, 0x66, +0x65, 0x74, 0x63, 0x68, 0x28, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x73, 0x5b, 0x30, 0x5d, 0x2c, +0x20, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, 0x79, 0x29, +0x2c, 0x09, 0x2f, 0x2a, 0x20, 0x42, 0x30, 0x3a, 0x20, 0x28, 0x2d, 0x31, 0x2c, 0x30, 0x29, 0x20, +0x2a, 0x2f, 0x0a, 0x09, 0x09, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x78, 0x63, 0x6f, 0x6f, 0x72, +0x64, 0x73, 0x5b, 0x30, 0x5d, 0x2c, 0x20, 0x79, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x73, 0x5b, 0x30, +0x5d, 0x29, 0x2c, 0x09, 0x09, 0x2f, 0x2a, 0x20, 0x44, 0x30, 0x3a, 0x20, 0x28, 0x2d, 0x31, 0x2c, +0x2d, 0x31, 0x29, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x09, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x78, +0x63, 0x6f, 0x6f, 0x72, 0x64, 0x73, 0x5b, 0x31, 0x5d, 0x2c, 0x20, 0x79, 0x63, 0x6f, 0x6f, 0x72, +0x64, 0x73, 0x5b, 0x30, 0x5d, 0x29, 0x29, 0x3b, 0x09, 0x09, 0x2f, 0x2a, 0x20, 0x44, 0x31, 0x3a, +0x20, 0x28, 0x31, 0x2c, 0x2d, 0x31, 0x29, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x76, 0x65, 0x63, 0x34, +0x20, 0x74, 0x65, 0x6d, 0x70, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x0a, 0x09, 0x09, +0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x74, +0x65, 0x73, 0x2e, 0x78, 0x2c, 0x20, 0x79, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x73, 0x5b, 0x31, 0x5d, +0x29, 0x2c, 0x09, 0x2f, 0x2a, 0x20, 0x41, 0x31, 0x3a, 0x20, 0x28, 0x30, 0x2c, 0x31, 0x29, 0x20, +0x2a, 0x2f, 0x0a, 0x09, 0x09, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x78, 0x63, 0x6f, 0x6f, 0x72, +0x64, 0x73, 0x5b, 0x31, 0x5d, 0x2c, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x62, 0x79, +0x74, 0x65, 0x73, 0x2e, 0x79, 0x29, 0x2c, 0x09, 0x2f, 0x2a, 0x20, 0x42, 0x31, 0x3a, 0x20, 0x28, +0x31, 0x2c, 0x30, 0x29, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x09, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, +0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x73, 0x5b, 0x31, 0x5d, 0x2c, 0x20, 0x79, 0x63, 0x6f, 0x6f, +0x72, 0x64, 0x73, 0x5b, 0x31, 0x5d, 0x29, 0x2c, 0x09, 0x09, 0x2f, 0x2a, 0x20, 0x44, 0x33, 0x3a, +0x20, 0x28, 0x31, 0x2c, 0x31, 0x29, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x09, 0x66, 0x65, 0x74, 0x63, +0x68, 0x28, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x73, 0x5b, 0x30, 0x5d, 0x2c, 0x20, 0x79, 0x63, +0x6f, 0x6f, 0x72, 0x64, 0x73, 0x5b, 0x31, 0x5d, 0x29, 0x29, 0x3b, 0x09, 0x09, 0x2f, 0x2a, 0x20, +0x44, 0x32, 0x3a, 0x20, 0x28, 0x2d, 0x31, 0x2c, 0x31, 0x29, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x70, +0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x28, 0x70, 0x61, 0x74, 0x74, 0x65, +0x72, 0x6e, 0x73, 0x20, 0x2b, 0x20, 0x74, 0x65, 0x6d, 0x70, 0x29, 0x20, 0x2a, 0x20, 0x30, 0x2e, +0x35, 0x3b, 0x0a, 0x09, 0x09, 0x2f, 0x2a, 0x20, 0x2e, 0x78, 0x20, 0x3d, 0x20, 0x28, 0x41, 0x30, +0x20, 0x2b, 0x20, 0x41, 0x31, 0x29, 0x20, 0x2f, 0x20, 0x32, 0x2e, 0x30, 0x2c, 0x20, 0x2e, 0x79, +0x20, 0x3d, 0x20, 0x28, 0x42, 0x30, 0x20, 0x2b, 0x20, 0x42, 0x31, 0x29, 0x20, 0x2f, 0x20, 0x32, +0x2e, 0x30, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x09, 0x2f, 0x2a, 0x20, 0x2e, 0x7a, 0x20, 0x3d, 0x20, +0x28, 0x44, 0x30, 0x20, 0x2b, 0x20, 0x44, 0x33, 0x29, 0x20, 0x2f, 0x20, 0x32, 0x2e, 0x30, 0x2c, +0x20, 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x28, 0x44, 0x31, 0x20, 0x2b, 0x20, 0x44, 0x32, 0x29, 0x20, +0x2f, 0x20, 0x32, 0x2e, 0x30, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, +0x6e, 0x73, 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x28, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x73, +0x2e, 0x7a, 0x20, 0x2b, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x73, 0x2e, 0x77, 0x29, +0x20, 0x2a, 0x20, 0x30, 0x2e, 0x35, 0x3b, 0x0a, 0x09, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, +0x73, 0x2e, 0x7a, 0x20, 0x3d, 0x20, 0x28, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x73, 0x2e, +0x78, 0x20, 0x2b, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x73, 0x2e, 0x79, 0x29, 0x20, +0x2a, 0x20, 0x30, 0x2e, 0x35, 0x3b, 0x0a, 0x0a, 0x09, 0x72, 0x67, 0x62, 0x20, 0x3d, 0x20, 0x65, +0x76, 0x65, 0x6e, 0x5f, 0x63, 0x6f, 0x6c, 0x20, 0x3f, 0x0a, 0x09, 0x09, 0x28, 0x65, 0x76, 0x65, +0x6e, 0x5f, 0x72, 0x6f, 0x77, 0x20, 0x3f, 0x0a, 0x09, 0x09, 0x09, 0x76, 0x65, 0x63, 0x33, 0x28, +0x43, 0x2c, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x73, 0x2e, 0x7a, 0x77, 0x29, 0x20, +0x3a, 0x0a, 0x09, 0x09, 0x09, 0x76, 0x65, 0x63, 0x33, 0x28, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, +0x6e, 0x73, 0x2e, 0x78, 0x2c, 0x20, 0x43, 0x2c, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, +0x73, 0x2e, 0x79, 0x29, 0x29, 0x20, 0x3a, 0x0a, 0x09, 0x09, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x5f, +0x72, 0x6f, 0x77, 0x20, 0x3f, 0x0a, 0x09, 0x09, 0x09, 0x76, 0x65, 0x63, 0x33, 0x28, 0x70, 0x61, +0x74, 0x74, 0x65, 0x72, 0x6e, 0x73, 0x2e, 0x79, 0x2c, 0x20, 0x43, 0x2c, 0x20, 0x70, 0x61, 0x74, +0x74, 0x65, 0x72, 0x6e, 0x73, 0x2e, 0x78, 0x29, 0x20, 0x3a, 0x0a, 0x09, 0x09, 0x09, 0x76, 0x65, +0x63, 0x33, 0x28, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x73, 0x2e, 0x77, 0x7a, 0x2c, 0x20, +0x43, 0x29, 0x29, 0x3b, 0x0a, 0x0a, 0x09, 0x72, 0x67, 0x62, 0x20, 0x3d, 0x20, 0x72, 0x67, 0x62, +0x20, 0x2d, 0x20, 0x62, 0x6c, 0x61, 0x63, 0x6b, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x3b, 0x0a, 0x0a, +0x09, 0x2f, 0x2a, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x43, 0x43, 0x4d, 0x20, 0x69, 0x73, +0x20, 0x61, 0x20, 0x33, 0x78, 0x33, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, +0x72, 0x6d, 0x61, 0x74, 0x0a, 0x09, 0x20, 0x2a, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x2b, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, +0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x7c, 0x20, 0x52, 0x65, 0x64, 0x52, 0x65, 0x64, 0x47, +0x61, 0x69, 0x6e, 0x20, 0x20, 0x20, 0x7c, 0x20, 0x52, 0x65, 0x64, 0x47, 0x72, 0x65, 0x65, 0x6e, +0x47, 0x61, 0x69, 0x6e, 0x20, 0x20, 0x20, 0x7c, 0x20, 0x52, 0x65, 0x64, 0x42, 0x6c, 0x75, 0x65, +0x47, 0x61, 0x69, 0x6e, 0x20, 0x20, 0x20, 0x7c, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x2b, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, +0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x7c, 0x20, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x52, 0x65, +0x64, 0x47, 0x61, 0x69, 0x6e, 0x20, 0x7c, 0x20, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x47, 0x72, 0x65, +0x65, 0x6e, 0x47, 0x61, 0x69, 0x6e, 0x20, 0x7c, 0x20, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x42, 0x6c, +0x75, 0x65, 0x47, 0x61, 0x69, 0x6e, 0x20, 0x7c, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x2b, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, +0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x7c, 0x20, 0x42, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x64, +0x47, 0x61, 0x69, 0x6e, 0x20, 0x20, 0x7c, 0x20, 0x20, 0x42, 0x6c, 0x75, 0x65, 0x47, 0x72, 0x65, +0x65, 0x6e, 0x47, 0x61, 0x69, 0x6e, 0x20, 0x7c, 0x20, 0x42, 0x6c, 0x75, 0x65, 0x42, 0x6c, 0x75, +0x65, 0x47, 0x61, 0x69, 0x6e, 0x20, 0x20, 0x7c, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x2b, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, +0x0a, 0x09, 0x20, 0x2a, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x52, 0x6f, 0x75, 0x74, 0x20, +0x3d, 0x20, 0x52, 0x65, 0x64, 0x52, 0x65, 0x64, 0x47, 0x61, 0x69, 0x6e, 0x20, 0x2a, 0x20, 0x52, +0x69, 0x6e, 0x20, 0x2b, 0x20, 0x52, 0x65, 0x64, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x47, 0x61, 0x69, +0x6e, 0x20, 0x2a, 0x20, 0x47, 0x69, 0x6e, 0x20, 0x2b, 0x20, 0x52, 0x65, 0x64, 0x42, 0x6c, 0x75, +0x65, 0x47, 0x61, 0x69, 0x6e, 0x20, 0x2a, 0x20, 0x42, 0x69, 0x6e, 0x0a, 0x09, 0x20, 0x2a, 0x20, +0x20, 0x20, 0x47, 0x6f, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x52, 0x65, +0x64, 0x47, 0x61, 0x69, 0x6e, 0x20, 0x2a, 0x20, 0x52, 0x69, 0x6e, 0x20, 0x2b, 0x20, 0x47, 0x72, +0x65, 0x65, 0x6e, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x47, 0x61, 0x69, 0x6e, 0x20, 0x2a, 0x20, 0x47, +0x69, 0x6e, 0x20, 0x2b, 0x20, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x42, 0x6c, 0x75, 0x65, 0x47, 0x61, +0x69, 0x6e, 0x20, 0x2a, 0x20, 0x42, 0x69, 0x6e, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x42, +0x6f, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x42, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x64, 0x47, 0x61, 0x69, +0x6e, 0x20, 0x2a, 0x20, 0x52, 0x69, 0x6e, 0x20, 0x2b, 0x20, 0x42, 0x6c, 0x75, 0x65, 0x47, 0x72, +0x65, 0x65, 0x6e, 0x47, 0x61, 0x69, 0x6e, 0x20, 0x2a, 0x20, 0x47, 0x69, 0x6e, 0x20, 0x2b, 0x20, +0x42, 0x6c, 0x75, 0x65, 0x42, 0x6c, 0x75, 0x65, 0x47, 0x61, 0x69, 0x6e, 0x20, 0x2a, 0x20, 0x42, +0x69, 0x6e, 0x0a, 0x09, 0x20, 0x2a, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x57, 0x65, 0x20, +0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x47, 0x50, +0x55, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, +0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x6c, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, +0x6d, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x33, 0x66, 0x28, 0x2e, 0x2e, 0x2c, 0x20, 0x2e, 0x2e, +0x2c, 0x20, 0x47, 0x4c, 0x5f, 0x46, 0x41, 0x4c, 0x53, 0x45, 0x2c, 0x20, 0x63, 0x63, 0x6d, 0x29, +0x3b, 0x0a, 0x09, 0x20, 0x2a, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x43, 0x50, 0x55, 0x0a, +0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x63, 0x63, 0x6d, 0x20, +0x5b, 0x5d, 0x20, 0x3d, 0x20, 0x7b, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x64, 0x52, 0x65, 0x64, 0x47, 0x61, 0x69, +0x6e, 0x2c, 0x20, 0x20, 0x20, 0x52, 0x65, 0x64, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x47, 0x61, 0x69, +0x6e, 0x2c, 0x20, 0x20, 0x20, 0x52, 0x65, 0x64, 0x42, 0x6c, 0x75, 0x65, 0x47, 0x61, 0x69, 0x6e, +0x2c, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x52, 0x65, 0x64, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x20, +0x47, 0x72, 0x65, 0x65, 0x6e, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x20, +0x47, 0x72, 0x65, 0x65, 0x6e, 0x42, 0x6c, 0x75, 0x65, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x0a, 0x09, +0x20, 0x2a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x42, +0x6c, 0x75, 0x65, 0x52, 0x65, 0x64, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x20, 0x20, 0x42, 0x6c, 0x75, +0x65, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x20, 0x20, 0x42, 0x6c, 0x75, +0x65, 0x42, 0x6c, 0x75, 0x65, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, +0x20, 0x7d, 0x3b, 0x0a, 0x09, 0x20, 0x2a, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x47, 0x50, +0x55, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x63, 0x63, 0x6d, 0x20, 0x3d, 0x20, 0x7b, 0x0a, +0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x52, 0x65, 0x64, 0x52, 0x65, 0x64, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x20, 0x20, 0x20, 0x47, 0x72, +0x65, 0x65, 0x6e, 0x52, 0x65, 0x64, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x20, 0x20, 0x20, 0x42, 0x6c, +0x75, 0x65, 0x52, 0x65, 0x64, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x64, 0x47, 0x72, +0x65, 0x65, 0x6e, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x20, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x47, 0x72, +0x65, 0x65, 0x6e, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x20, 0x42, 0x6c, 0x75, 0x65, 0x47, 0x72, 0x65, +0x65, 0x6e, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x64, 0x42, 0x6c, 0x75, 0x65, 0x47, +0x61, 0x69, 0x6e, 0x2c, 0x20, 0x20, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x42, 0x6c, 0x75, 0x65, 0x47, +0x61, 0x69, 0x6e, 0x2c, 0x20, 0x20, 0x42, 0x6c, 0x75, 0x65, 0x42, 0x6c, 0x75, 0x65, 0x47, 0x61, +0x69, 0x6e, 0x2c, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x09, 0x20, 0x2a, 0x0a, +0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x48, 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x20, 0x74, 0x68, +0x65, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, +0x68, 0x65, 0x20, 0x6d, 0x61, 0x74, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x74, 0x79, 0x70, 0x65, +0x20, 0x69, 0x73, 0x20, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x20, 0x6d, 0x61, 0x6a, 0x6f, 0x72, +0x20, 0x68, 0x65, 0x6e, 0x63, 0x65, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x63, 0x63, 0x6d, +0x5b, 0x30, 0x5d, 0x5b, 0x30, 0x5d, 0x20, 0x3d, 0x20, 0x52, 0x65, 0x64, 0x52, 0x65, 0x64, 0x47, +0x61, 0x69, 0x6e, 0x2c, 0x20, 0x63, 0x63, 0x6d, 0x5b, 0x30, 0x5d, 0x5b, 0x31, 0x5d, 0x20, 0x3d, +0x20, 0x52, 0x65, 0x64, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x20, 0x63, +0x63, 0x6d, 0x5b, 0x30, 0x5d, 0x5b, 0x32, 0x5d, 0x20, 0x3d, 0x20, 0x52, 0x65, 0x64, 0x42, 0x6c, +0x75, 0x65, 0x47, 0x61, 0x69, 0x6e, 0x0a, 0x09, 0x20, 0x2a, 0x0a, 0x09, 0x20, 0x2a, 0x2f, 0x0a, +0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x72, 0x69, 0x6e, 0x2c, 0x20, 0x67, 0x69, 0x6e, 0x2c, +0x20, 0x62, 0x69, 0x6e, 0x3b, 0x0a, 0x09, 0x72, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x72, 0x67, 0x62, +0x2e, 0x72, 0x3b, 0x0a, 0x09, 0x67, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x72, 0x67, 0x62, 0x2e, 0x67, +0x3b, 0x0a, 0x09, 0x62, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x72, 0x67, 0x62, 0x2e, 0x62, 0x3b, 0x0a, +0x0a, 0x09, 0x72, 0x67, 0x62, 0x2e, 0x72, 0x20, 0x3d, 0x20, 0x28, 0x72, 0x69, 0x6e, 0x20, 0x2a, +0x20, 0x63, 0x63, 0x6d, 0x5b, 0x30, 0x5d, 0x5b, 0x30, 0x5d, 0x29, 0x20, 0x2b, 0x20, 0x28, 0x67, +0x69, 0x6e, 0x20, 0x2a, 0x20, 0x63, 0x63, 0x6d, 0x5b, 0x30, 0x5d, 0x5b, 0x31, 0x5d, 0x29, 0x20, +0x2b, 0x20, 0x28, 0x62, 0x69, 0x6e, 0x20, 0x2a, 0x20, 0x63, 0x63, 0x6d, 0x5b, 0x30, 0x5d, 0x5b, +0x32, 0x5d, 0x29, 0x3b, 0x0a, 0x09, 0x72, 0x67, 0x62, 0x2e, 0x67, 0x20, 0x3d, 0x20, 0x28, 0x72, +0x69, 0x6e, 0x20, 0x2a, 0x20, 0x63, 0x63, 0x6d, 0x5b, 0x31, 0x5d, 0x5b, 0x30, 0x5d, 0x29, 0x20, +0x2b, 0x20, 0x28, 0x67, 0x69, 0x6e, 0x20, 0x2a, 0x20, 0x63, 0x63, 0x6d, 0x5b, 0x31, 0x5d, 0x5b, +0x31, 0x5d, 0x29, 0x20, 0x2b, 0x20, 0x28, 0x62, 0x69, 0x6e, 0x20, 0x2a, 0x20, 0x63, 0x63, 0x6d, +0x5b, 0x31, 0x5d, 0x5b, 0x32, 0x5d, 0x29, 0x3b, 0x0a, 0x09, 0x72, 0x67, 0x62, 0x2e, 0x62, 0x20, +0x3d, 0x20, 0x28, 0x72, 0x69, 0x6e, 0x20, 0x2a, 0x20, 0x63, 0x63, 0x6d, 0x5b, 0x32, 0x5d, 0x5b, +0x30, 0x5d, 0x29, 0x20, 0x2b, 0x20, 0x28, 0x67, 0x69, 0x6e, 0x20, 0x2a, 0x20, 0x63, 0x63, 0x6d, +0x5b, 0x32, 0x5d, 0x5b, 0x31, 0x5d, 0x29, 0x20, 0x2b, 0x20, 0x28, 0x62, 0x69, 0x6e, 0x20, 0x2a, +0x20, 0x63, 0x63, 0x6d, 0x5b, 0x32, 0x5d, 0x5b, 0x32, 0x5d, 0x29, 0x3b, 0x0a, 0x0a, 0x09, 0x2f, +0x2a, 0x0a, 0x09, 0x20, 0x2a, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x73, 0x74, 0x0a, 0x09, +0x20, 0x2a, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x73, 0x74, 0x45, 0x78, 0x70, 0x20, 0x30, +0x2e, 0x2e, 0x32, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x73, 0x74, 0x20, 0x74, 0x6f, 0x20, +0x30, 0x2e, 0x2e, 0x69, 0x6e, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x79, 0x3b, 0x20, 0x61, 0x76, 0x6f, +0x69, 0x64, 0x20, 0x61, 0x63, 0x74, 0x75, 0x61, 0x6c, 0x20, 0x69, 0x6e, 0x66, 0x69, 0x6e, 0x69, +0x74, 0x79, 0x20, 0x61, 0x74, 0x20, 0x74, 0x61, 0x6e, 0x28, 0x70, 0x69, 0x2f, 0x32, 0x29, 0x0a, +0x09, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x72, 0x67, 0x62, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x6d, +0x70, 0x28, 0x72, 0x67, 0x62, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, +0x3b, 0x0a, 0x09, 0x72, 0x67, 0x62, 0x2e, 0x72, 0x20, 0x3d, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, +0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x73, 0x74, 0x28, 0x72, 0x67, 0x62, 0x2e, 0x72, 0x29, +0x3b, 0x0a, 0x09, 0x72, 0x67, 0x62, 0x2e, 0x67, 0x20, 0x3d, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, +0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x73, 0x74, 0x28, 0x72, 0x67, 0x62, 0x2e, 0x67, 0x29, +0x3b, 0x0a, 0x09, 0x72, 0x67, 0x62, 0x2e, 0x62, 0x20, 0x3d, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, +0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x73, 0x74, 0x28, 0x72, 0x67, 0x62, 0x2e, 0x62, 0x29, +0x3b, 0x0a, 0x0a, 0x09, 0x2f, 0x2a, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x20, 0x67, 0x61, 0x6d, +0x6d, 0x61, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x20, +0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x72, +0x67, 0x62, 0x20, 0x3d, 0x20, 0x70, 0x6f, 0x77, 0x28, 0x72, 0x67, 0x62, 0x2c, 0x20, 0x76, 0x65, +0x63, 0x33, 0x28, 0x67, 0x61, 0x6d, 0x6d, 0x61, 0x29, 0x29, 0x3b, 0x0a, 0x0a, 0x23, 0x69, 0x66, +0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x28, 0x53, 0x57, 0x41, 0x50, 0x5f, 0x42, +0x4c, 0x55, 0x45, 0x29, 0x0a, 0x09, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, +0x6f, 0x72, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x72, 0x67, 0x62, 0x2e, 0x62, 0x67, +0x72, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x23, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, +0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x76, +0x65, 0x63, 0x34, 0x28, 0x72, 0x67, 0x62, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x23, +0x65, 0x6e, 0x64, 0x69, 0x66, 0x0a, 0x7d, 0x0a, +}; + +const unsigned int bayer_1x_packed_frag_len=9144; + +unsigned char const bayer_unpacked_frag [] = { +0x2f, 0x2a, 0x20, 0x53, 0x50, 0x44, 0x58, 0x2d, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x2d, +0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x3a, 0x20, 0x42, 0x53, 0x44, 0x2d, +0x32, 0x2d, 0x43, 0x6c, 0x61, 0x75, 0x73, 0x65, 0x20, 0x2a, 0x2f, 0x0a, 0x2f, 0x2a, 0x0a, 0x46, +0x72, 0x6f, 0x6d, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6a, 0x67, 0x74, 0x2e, 0x61, +0x6b, 0x70, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x61, 0x70, 0x65, +0x72, 0x73, 0x2f, 0x4d, 0x63, 0x47, 0x75, 0x69, 0x72, 0x65, 0x30, 0x38, 0x2f, 0x0a, 0x0a, 0x45, +0x66, 0x66, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x2c, 0x20, 0x48, 0x69, 0x67, 0x68, 0x2d, 0x51, +0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x20, 0x42, 0x61, 0x79, 0x65, 0x72, 0x20, 0x44, 0x65, 0x6d, +0x6f, 0x73, 0x61, 0x69, 0x63, 0x20, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x20, +0x6f, 0x6e, 0x20, 0x47, 0x50, 0x55, 0x73, 0x0a, 0x0a, 0x4d, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x20, +0x4d, 0x63, 0x47, 0x75, 0x69, 0x72, 0x65, 0x0a, 0x0a, 0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x61, +0x70, 0x65, 0x72, 0x20, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x69, +0x73, 0x73, 0x75, 0x65, 0x20, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x20, 0x31, 0x33, 0x2c, 0x20, +0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x34, 0x2e, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, +0x2d, 0x2d, 0x2d, 0x0a, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, +0x29, 0x20, 0x32, 0x30, 0x30, 0x38, 0x2c, 0x20, 0x4d, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x20, 0x4d, +0x63, 0x47, 0x75, 0x69, 0x72, 0x65, 0x2e, 0x20, 0x41, 0x6c, 0x6c, 0x20, 0x72, 0x69, 0x67, 0x68, +0x74, 0x73, 0x20, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x4d, 0x6f, +0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x4c, 0x69, 0x6e, 0x61, 0x72, 0x6f, +0x20, 0x4c, 0x74, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, +0x65, 0x20, 0x69, 0x74, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x6c, 0x69, 0x62, 0x63, 0x61, 0x6d, +0x65, 0x72, 0x61, 0x2e, 0x0a, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, +0x43, 0x29, 0x20, 0x32, 0x30, 0x32, 0x31, 0x2c, 0x20, 0x4c, 0x69, 0x6e, 0x61, 0x72, 0x6f, 0x0a, +0x2a, 0x2f, 0x0a, 0x0a, 0x2f, 0x2f, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x53, 0x68, 0x61, 0x64, +0x65, 0x72, 0x0a, 0x23, 0x69, 0x66, 0x64, 0x65, 0x66, 0x20, 0x47, 0x4c, 0x5f, 0x45, 0x53, 0x0a, +0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, +0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3b, 0x0a, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x0a, 0x0a, 0x2f, +0x2a, 0x2a, 0x20, 0x4d, 0x6f, 0x6e, 0x6f, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x20, 0x52, 0x47, +0x42, 0x41, 0x20, 0x6f, 0x72, 0x20, 0x47, 0x4c, 0x5f, 0x4c, 0x55, 0x4d, 0x49, 0x4e, 0x41, 0x4e, +0x43, 0x45, 0x20, 0x42, 0x61, 0x79, 0x65, 0x72, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, +0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x2e, 0x2a, 0x2f, 0x0a, 0x75, 0x6e, 0x69, 0x66, +0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x5f, 0x79, 0x3b, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, +0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, +0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x79, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, +0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, +0x72, 0x6d, 0x20, 0x6d, 0x61, 0x74, 0x33, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x63, 0x63, 0x6d, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, +0x76, 0x65, 0x63, 0x33, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x62, 0x6c, 0x61, 0x63, 0x6b, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, +0x6f, 0x72, 0x6d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x67, 0x61, 0x6d, 0x6d, 0x61, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, +0x72, 0x6d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x73, 0x74, 0x45, 0x78, 0x70, 0x3b, 0x0a, +0x0a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x5f, 0x63, 0x6f, 0x6e, +0x74, 0x72, 0x61, 0x73, 0x74, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, +0x65, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x41, 0x70, 0x70, 0x6c, +0x79, 0x20, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x53, 0x2d, 0x63, 0x75, 0x72, 0x76, 0x65, +0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3c, +0x20, 0x30, 0x2e, 0x35, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, +0x74, 0x75, 0x72, 0x6e, 0x20, 0x30, 0x2e, 0x35, 0x20, 0x2a, 0x20, 0x70, 0x6f, 0x77, 0x28, 0x76, +0x61, 0x6c, 0x75, 0x65, 0x20, 0x2f, 0x20, 0x30, 0x2e, 0x35, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x74, +0x72, 0x61, 0x73, 0x74, 0x45, 0x78, 0x70, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, +0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, +0x6e, 0x20, 0x31, 0x2e, 0x30, 0x20, 0x2d, 0x20, 0x30, 0x2e, 0x35, 0x20, 0x2a, 0x20, 0x70, 0x6f, +0x77, 0x28, 0x28, 0x31, 0x2e, 0x30, 0x20, 0x2d, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x29, 0x20, +0x2f, 0x20, 0x30, 0x2e, 0x35, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x73, 0x74, 0x45, +0x78, 0x70, 0x29, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, +0x6e, 0x28, 0x76, 0x6f, 0x69, 0x64, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, +0x63, 0x33, 0x20, 0x72, 0x67, 0x62, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x23, 0x69, 0x66, +0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x28, 0x52, 0x41, 0x57, 0x31, 0x30, 0x50, 0x29, +0x0a, 0x20, 0x20, 0x20, 0x20, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x70, 0x69, 0x78, +0x65, 0x6c, 0x28, 0x70, 0x29, 0x20, 0x70, 0x2e, 0x72, 0x20, 0x2f, 0x20, 0x34, 0x2e, 0x30, 0x20, +0x2b, 0x20, 0x70, 0x2e, 0x67, 0x20, 0x2a, 0x20, 0x36, 0x34, 0x2e, 0x30, 0x0a, 0x20, 0x20, 0x20, +0x20, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x78, +0x2c, 0x20, 0x79, 0x29, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x28, 0x74, 0x65, 0x78, 0x74, 0x75, +0x72, 0x65, 0x32, 0x44, 0x28, 0x74, 0x65, 0x78, 0x5f, 0x79, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x32, +0x28, 0x78, 0x2c, 0x20, 0x79, 0x29, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x23, 0x65, 0x6c, +0x69, 0x66, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x28, 0x52, 0x41, 0x57, 0x31, 0x32, +0x50, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x70, +0x69, 0x78, 0x65, 0x6c, 0x28, 0x70, 0x29, 0x20, 0x70, 0x2e, 0x72, 0x20, 0x2f, 0x20, 0x31, 0x36, +0x2e, 0x30, 0x20, 0x2b, 0x20, 0x70, 0x2e, 0x67, 0x20, 0x2a, 0x20, 0x31, 0x36, 0x2e, 0x30, 0x0a, +0x20, 0x20, 0x20, 0x20, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x66, 0x65, 0x74, 0x63, +0x68, 0x28, 0x78, 0x2c, 0x20, 0x79, 0x29, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x28, 0x74, 0x65, +0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x28, 0x74, 0x65, 0x78, 0x5f, 0x79, 0x2c, 0x20, 0x76, +0x65, 0x63, 0x32, 0x28, 0x78, 0x2c, 0x20, 0x79, 0x29, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, +0x23, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, +0x65, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x78, 0x2c, 0x20, 0x79, 0x29, 0x20, 0x74, 0x65, +0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x28, 0x74, 0x65, 0x78, 0x5f, 0x79, 0x2c, 0x20, 0x76, +0x65, 0x63, 0x32, 0x28, 0x78, 0x2c, 0x20, 0x79, 0x29, 0x29, 0x2e, 0x72, 0x0a, 0x20, 0x20, 0x20, +0x20, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, +0x61, 0x74, 0x20, 0x43, 0x20, 0x3d, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x63, 0x65, 0x6e, +0x74, 0x65, 0x72, 0x2e, 0x78, 0x2c, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x79, 0x29, +0x3b, 0x20, 0x2f, 0x2f, 0x20, 0x28, 0x20, 0x30, 0x2c, 0x20, 0x30, 0x29, 0x0a, 0x20, 0x20, 0x20, +0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x6b, 0x43, 0x20, 0x3d, +0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x20, 0x34, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x36, 0x2e, 0x30, +0x2c, 0x20, 0x20, 0x35, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x35, 0x2e, 0x30, 0x29, 0x20, 0x2f, 0x20, +0x38, 0x2e, 0x30, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x44, 0x65, 0x74, +0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x6f, 0x66, 0x20, +0x66, 0x6f, 0x75, 0x72, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x70, 0x69, +0x78, 0x65, 0x6c, 0x73, 0x20, 0x77, 0x65, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6f, 0x6e, 0x2e, 0x0a, +0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, +0x74, 0x65, 0x20, 0x3d, 0x20, 0x6d, 0x6f, 0x64, 0x28, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x63, +0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x7a, 0x77, 0x29, 0x2c, 0x20, 0x32, 0x2e, 0x30, 0x29, 0x3b, +0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x44, 0x76, 0x65, 0x63, 0x20, +0x3d, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x5b, 0x31, 0x5d, 0x2c, +0x20, 0x79, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x5b, 0x31, 0x5d, 0x29, 0x2c, 0x20, 0x20, 0x2f, 0x2f, +0x20, 0x28, 0x2d, 0x31, 0x2c, 0x2d, 0x31, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x5b, 0x31, 0x5d, +0x2c, 0x20, 0x79, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x5b, 0x32, 0x5d, 0x29, 0x2c, 0x20, 0x20, 0x2f, +0x2f, 0x20, 0x28, 0x2d, 0x31, 0x2c, 0x20, 0x31, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x5b, 0x32, +0x5d, 0x2c, 0x20, 0x79, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x5b, 0x31, 0x5d, 0x29, 0x2c, 0x20, 0x20, +0x2f, 0x2f, 0x20, 0x28, 0x20, 0x31, 0x2c, 0x2d, 0x31, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x5b, +0x32, 0x5d, 0x2c, 0x20, 0x79, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x5b, 0x32, 0x5d, 0x29, 0x29, 0x3b, +0x20, 0x2f, 0x2f, 0x20, 0x28, 0x20, 0x31, 0x2c, 0x20, 0x31, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, +0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x50, 0x41, 0x54, 0x54, 0x45, 0x52, 0x4e, 0x20, 0x3d, 0x20, +0x28, 0x6b, 0x43, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x2a, 0x20, 0x43, 0x29, 0x2e, 0x78, 0x79, 0x7a, +0x7a, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x43, 0x61, 0x6e, 0x20, 0x61, +0x6c, 0x73, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x64, 0x6f, 0x74, 0x20, 0x70, 0x72, 0x6f, +0x64, 0x75, 0x63, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x28, 0x31, 0x2c, 0x31, 0x2c, 0x31, +0x2c, 0x31, 0x29, 0x20, 0x6f, 0x6e, 0x20, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x20, +0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x69, 0x73, 0x0a, 0x20, 0x20, +0x20, 0x20, 0x2f, 0x2f, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x6f, +0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x64, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, +0x20, 0x45, 0x71, 0x75, 0x69, 0x76, 0x61, 0x6c, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x3a, 0x20, +0x44, 0x20, 0x3d, 0x20, 0x44, 0x76, 0x65, 0x63, 0x5b, 0x30, 0x5d, 0x20, 0x2b, 0x20, 0x44, 0x76, +0x65, 0x63, 0x5b, 0x31, 0x5d, 0x20, 0x2b, 0x20, 0x44, 0x76, 0x65, 0x63, 0x5b, 0x32, 0x5d, 0x20, +0x2b, 0x20, 0x44, 0x76, 0x65, 0x63, 0x5b, 0x33, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x44, +0x76, 0x65, 0x63, 0x2e, 0x78, 0x79, 0x20, 0x2b, 0x3d, 0x20, 0x44, 0x76, 0x65, 0x63, 0x2e, 0x7a, +0x77, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x44, 0x76, 0x65, 0x63, 0x2e, 0x78, 0x20, 0x20, 0x2b, +0x3d, 0x20, 0x44, 0x76, 0x65, 0x63, 0x2e, 0x79, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, +0x65, 0x63, 0x34, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x34, +0x28, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, +0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x78, 0x2c, 0x20, 0x79, 0x43, 0x6f, 0x6f, 0x72, 0x64, +0x5b, 0x30, 0x5d, 0x29, 0x2c, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x28, 0x20, 0x30, 0x2c, 0x2d, +0x32, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, +0x28, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x78, 0x2c, 0x20, 0x79, 0x43, 0x6f, 0x6f, 0x72, +0x64, 0x5b, 0x31, 0x5d, 0x29, 0x2c, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x28, 0x20, 0x30, 0x2c, +0x2d, 0x31, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x65, 0x74, 0x63, +0x68, 0x28, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x5b, 0x30, 0x5d, 0x2c, 0x20, 0x63, 0x65, 0x6e, +0x74, 0x65, 0x72, 0x2e, 0x79, 0x29, 0x2c, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x28, 0x2d, 0x32, +0x2c, 0x20, 0x30, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x65, 0x74, +0x63, 0x68, 0x28, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x5b, 0x31, 0x5d, 0x2c, 0x20, 0x63, 0x65, +0x6e, 0x74, 0x65, 0x72, 0x2e, 0x79, 0x29, 0x29, 0x3b, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x28, 0x2d, +0x31, 0x2c, 0x20, 0x30, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, +0x74, 0x65, 0x6d, 0x70, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x0a, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x63, 0x65, 0x6e, 0x74, 0x65, +0x72, 0x2e, 0x78, 0x2c, 0x20, 0x79, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x5b, 0x33, 0x5d, 0x29, 0x2c, +0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x28, 0x20, 0x30, 0x2c, 0x20, 0x32, 0x29, 0x0a, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x63, 0x65, 0x6e, 0x74, +0x65, 0x72, 0x2e, 0x78, 0x2c, 0x20, 0x79, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x5b, 0x32, 0x5d, 0x29, +0x2c, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x28, 0x20, 0x30, 0x2c, 0x20, 0x31, 0x29, 0x0a, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x78, 0x43, 0x6f, +0x6f, 0x72, 0x64, 0x5b, 0x33, 0x5d, 0x2c, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x79, +0x29, 0x2c, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x28, 0x20, 0x32, 0x2c, 0x20, 0x30, 0x29, 0x0a, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x78, 0x43, +0x6f, 0x6f, 0x72, 0x64, 0x5b, 0x32, 0x5d, 0x2c, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, +0x79, 0x29, 0x29, 0x3b, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x28, 0x20, 0x31, 0x2c, 0x20, 0x30, 0x29, +0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x45, 0x76, 0x65, 0x6e, 0x20, 0x74, 0x68, +0x65, 0x20, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x74, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x69, +0x6c, 0x65, 0x72, 0x73, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x61, +0x62, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x2d, +0x66, 0x6f, 0x6c, 0x64, 0x20, 0x74, 0x68, 0x65, 0x73, 0x65, 0x20, 0x74, 0x6f, 0x0a, 0x20, 0x20, +0x20, 0x20, 0x2f, 0x2f, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, +0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, +0x4e, 0x6f, 0x74, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x6f, 0x6e, 0x20, 0x73, 0x63, 0x61, +0x6c, 0x61, 0x72, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x73, 0x20, 0x74, +0x68, 0x65, 0x73, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x73, 0x20, 0x66, +0x6f, 0x72, 0x63, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, +0x20, 0x6f, 0x66, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, +0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, +0x74, 0x73, 0x20, 0x74, 0x77, 0x69, 0x63, 0x65, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, +0x6e, 0x73, 0x74, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x6b, 0x41, 0x20, 0x3d, 0x20, 0x76, 0x65, +0x63, 0x34, 0x28, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x35, 0x2c, 0x20, 0x20, +0x30, 0x2e, 0x35, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x20, 0x2f, 0x20, 0x38, 0x2e, 0x30, +0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x76, 0x65, 0x63, 0x34, +0x20, 0x6b, 0x42, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x20, 0x32, 0x2e, 0x30, 0x2c, +0x20, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x34, 0x2e, +0x30, 0x29, 0x20, 0x2f, 0x20, 0x38, 0x2e, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, +0x6e, 0x73, 0x74, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x6b, 0x44, 0x20, 0x3d, 0x20, 0x76, 0x65, +0x63, 0x34, 0x28, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x32, 0x2e, 0x30, 0x2c, 0x20, 0x2d, +0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x20, 0x2f, 0x20, 0x38, 0x2e, 0x30, +0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x65, 0x72, +0x76, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x72, 0x65, 0x67, 0x69, +0x73, 0x74, 0x65, 0x72, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x61, 0x6b, 0x65, 0x20, 0x61, +0x64, 0x76, 0x61, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x66, 0x72, 0x65, 0x65, +0x20, 0x73, 0x77, 0x69, 0x7a, 0x7a, 0x6c, 0x65, 0x20, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x61, 0x64, +0x0a, 0x20, 0x20, 0x20, 0x20, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x6b, 0x45, 0x20, +0x28, 0x6b, 0x41, 0x2e, 0x78, 0x79, 0x77, 0x7a, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x23, 0x64, +0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x6b, 0x46, 0x20, 0x28, 0x6b, 0x42, 0x2e, 0x78, 0x79, 0x77, +0x7a, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x2b, 0x3d, +0x20, 0x74, 0x65, 0x6d, 0x70, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x54, +0x68, 0x65, 0x72, 0x65, 0x20, 0x61, 0x72, 0x65, 0x20, 0x66, 0x69, 0x76, 0x65, 0x20, 0x66, 0x69, +0x6c, 0x74, 0x65, 0x72, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x73, 0x20, 0x28, 0x69, +0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2c, 0x20, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x2c, 0x20, +0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, +0x74, 0x68, 0x65, 0x74, 0x61, 0x2c, 0x20, 0x70, 0x68, 0x69, 0x29, 0x2e, 0x20, 0x20, 0x50, 0x72, +0x65, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x72, +0x6d, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x66, 0x20, 0x74, +0x68, 0x65, 0x6d, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, +0x20, 0x2f, 0x2f, 0x20, 0x75, 0x73, 0x65, 0x20, 0x73, 0x77, 0x69, 0x7a, 0x7a, 0x6c, 0x65, 0x73, +0x20, 0x74, 0x6f, 0x20, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x6f, +0x6c, 0x6f, 0x72, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x2e, 0x0a, 0x20, 0x20, +0x20, 0x20, 0x2f, 0x2f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x43, 0x68, 0x61, 0x6e, +0x6e, 0x65, 0x6c, 0x20, 0x20, 0x20, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x0a, 0x20, 0x20, +0x20, 0x20, 0x2f, 0x2f, 0x20, 0x20, 0x20, 0x78, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, +0x72, 0x6f, 0x73, 0x73, 0x20, 0x20, 0x20, 0x28, 0x65, 0x2e, 0x67, 0x2e, 0x2c, 0x20, 0x45, 0x45, +0x20, 0x47, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x20, 0x20, 0x79, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x20, 0x28, 0x65, 0x2e, +0x67, 0x2e, 0x2c, 0x20, 0x45, 0x45, 0x20, 0x42, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, +0x20, 0x20, 0x20, 0x7a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x65, 0x74, 0x61, +0x20, 0x20, 0x20, 0x28, 0x65, 0x2e, 0x67, 0x2e, 0x2c, 0x20, 0x45, 0x4f, 0x20, 0x52, 0x29, 0x0a, +0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x20, 0x20, 0x77, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x70, 0x68, 0x69, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x65, 0x2e, 0x67, 0x2e, 0x2c, 0x20, +0x45, 0x4f, 0x20, 0x52, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, +0x65, 0x20, 0x41, 0x20, 0x28, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5b, 0x30, 0x5d, 0x29, 0x0a, 0x20, +0x20, 0x20, 0x20, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x42, 0x20, 0x28, 0x76, 0x61, +0x6c, 0x75, 0x65, 0x5b, 0x31, 0x5d, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x23, 0x64, 0x65, 0x66, +0x69, 0x6e, 0x65, 0x20, 0x44, 0x20, 0x28, 0x44, 0x76, 0x65, 0x63, 0x2e, 0x78, 0x29, 0x0a, 0x20, +0x20, 0x20, 0x20, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x45, 0x20, 0x28, 0x76, 0x61, +0x6c, 0x75, 0x65, 0x5b, 0x32, 0x5d, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x23, 0x64, 0x65, 0x66, +0x69, 0x6e, 0x65, 0x20, 0x46, 0x20, 0x28, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5b, 0x33, 0x5d, 0x29, +0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x41, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x7a, +0x65, 0x72, 0x6f, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x20, 0x4f, 0x6e, +0x20, 0x61, 0x20, 0x73, 0x63, 0x61, 0x6c, 0x61, 0x72, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, +0x73, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x73, 0x61, 0x76, 0x65, 0x73, 0x20, 0x74, +0x77, 0x6f, 0x20, 0x4d, 0x41, 0x44, 0x44, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, +0x61, 0x6e, 0x64, 0x20, 0x69, 0x74, 0x20, 0x68, 0x61, 0x73, 0x20, 0x6e, 0x6f, 0x20, 0x65, 0x66, +0x66, 0x65, 0x63, 0x74, 0x20, 0x6f, 0x6e, 0x20, 0x61, 0x20, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, +0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x20, +0x50, 0x41, 0x54, 0x54, 0x45, 0x52, 0x4e, 0x2e, 0x79, 0x7a, 0x77, 0x20, 0x2b, 0x3d, 0x20, 0x28, +0x6b, 0x44, 0x2e, 0x79, 0x7a, 0x20, 0x2a, 0x20, 0x44, 0x29, 0x2e, 0x78, 0x79, 0x79, 0x3b, 0x0a, +0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x41, 0x54, 0x54, 0x45, 0x52, 0x4e, 0x20, 0x2b, 0x3d, 0x20, +0x28, 0x6b, 0x41, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x2a, 0x20, 0x41, 0x29, 0x2e, 0x78, 0x79, 0x7a, +0x78, 0x20, 0x2b, 0x20, 0x28, 0x6b, 0x45, 0x2e, 0x78, 0x79, 0x77, 0x20, 0x2a, 0x20, 0x45, 0x29, +0x2e, 0x78, 0x79, 0x78, 0x7a, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x41, 0x54, 0x54, 0x45, +0x52, 0x4e, 0x2e, 0x78, 0x77, 0x20, 0x20, 0x2b, 0x3d, 0x20, 0x6b, 0x42, 0x2e, 0x78, 0x77, 0x20, +0x2a, 0x20, 0x42, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x41, 0x54, 0x54, 0x45, 0x52, 0x4e, +0x2e, 0x78, 0x7a, 0x20, 0x20, 0x2b, 0x3d, 0x20, 0x6b, 0x46, 0x2e, 0x78, 0x7a, 0x20, 0x2a, 0x20, +0x46, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x67, 0x62, 0x20, 0x3d, 0x20, 0x20, 0x28, +0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x2e, 0x79, 0x20, 0x3d, 0x3d, 0x20, 0x30, +0x2e, 0x30, 0x29, 0x20, 0x3f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, +0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x2e, 0x78, 0x20, 0x3d, 0x3d, 0x20, 0x30, +0x2e, 0x30, 0x29, 0x20, 0x3f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x43, 0x2c, 0x20, 0x50, 0x41, 0x54, 0x54, 0x45, 0x52, +0x4e, 0x2e, 0x78, 0x79, 0x29, 0x20, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x50, 0x41, 0x54, 0x54, 0x45, 0x52, 0x4e, +0x2e, 0x7a, 0x2c, 0x20, 0x43, 0x2c, 0x20, 0x50, 0x41, 0x54, 0x54, 0x45, 0x52, 0x4e, 0x2e, 0x77, +0x29, 0x29, 0x20, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x61, +0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x2e, 0x78, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x2e, +0x30, 0x29, 0x20, 0x3f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x50, 0x41, 0x54, 0x54, 0x45, 0x52, 0x4e, 0x2e, 0x77, 0x2c, +0x20, 0x43, 0x2c, 0x20, 0x50, 0x41, 0x54, 0x54, 0x45, 0x52, 0x4e, 0x2e, 0x7a, 0x29, 0x20, 0x3a, +0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, +0x33, 0x28, 0x50, 0x41, 0x54, 0x54, 0x45, 0x52, 0x4e, 0x2e, 0x79, 0x78, 0x2c, 0x20, 0x43, 0x29, +0x29, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x67, 0x62, 0x20, 0x3d, 0x20, 0x72, 0x67, +0x62, 0x20, 0x2d, 0x20, 0x62, 0x6c, 0x61, 0x63, 0x6b, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x3b, 0x0a, +0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x20, +0x20, 0x43, 0x43, 0x4d, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x33, 0x78, 0x33, 0x20, 0x69, 0x6e, +0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, +0x20, 0x2a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x2b, 0x2d, 0x2d, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, 0x2d, 0x2d, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, 0x2d, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x0a, 0x20, 0x20, +0x20, 0x20, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x7c, 0x20, 0x52, 0x65, 0x64, 0x52, 0x65, 0x64, 0x47, +0x61, 0x69, 0x6e, 0x20, 0x20, 0x20, 0x7c, 0x20, 0x52, 0x65, 0x64, 0x47, 0x72, 0x65, 0x65, 0x6e, +0x47, 0x61, 0x69, 0x6e, 0x20, 0x20, 0x20, 0x7c, 0x20, 0x52, 0x65, 0x64, 0x42, 0x6c, 0x75, 0x65, +0x47, 0x61, 0x69, 0x6e, 0x20, 0x20, 0x20, 0x7c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2a, 0x20, +0x20, 0x20, 0x2b, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, +0x2d, 0x2b, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, +0x2d, 0x2d, 0x2b, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, +0x2d, 0x2d, 0x2b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x7c, 0x20, 0x47, +0x72, 0x65, 0x65, 0x6e, 0x52, 0x65, 0x64, 0x47, 0x61, 0x69, 0x6e, 0x20, 0x7c, 0x20, 0x47, 0x72, +0x65, 0x65, 0x6e, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x47, 0x61, 0x69, 0x6e, 0x20, 0x7c, 0x20, 0x47, +0x72, 0x65, 0x65, 0x6e, 0x42, 0x6c, 0x75, 0x65, 0x47, 0x61, 0x69, 0x6e, 0x20, 0x7c, 0x0a, 0x20, +0x20, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x2b, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2a, +0x20, 0x20, 0x20, 0x7c, 0x20, 0x42, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x64, 0x47, 0x61, 0x69, 0x6e, +0x20, 0x20, 0x7c, 0x20, 0x20, 0x42, 0x6c, 0x75, 0x65, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x47, 0x61, +0x69, 0x6e, 0x20, 0x7c, 0x20, 0x42, 0x6c, 0x75, 0x65, 0x42, 0x6c, 0x75, 0x65, 0x47, 0x61, 0x69, +0x6e, 0x20, 0x20, 0x7c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x2b, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2b, 0x0a, +0x20, 0x20, 0x20, 0x20, 0x20, 0x2a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x20, 0x20, +0x52, 0x6f, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x52, 0x65, 0x64, 0x52, 0x65, 0x64, 0x47, 0x61, 0x69, +0x6e, 0x20, 0x2a, 0x20, 0x52, 0x69, 0x6e, 0x20, 0x2b, 0x20, 0x52, 0x65, 0x64, 0x47, 0x72, 0x65, +0x65, 0x6e, 0x47, 0x61, 0x69, 0x6e, 0x20, 0x2a, 0x20, 0x47, 0x69, 0x6e, 0x20, 0x2b, 0x20, 0x52, +0x65, 0x64, 0x42, 0x6c, 0x75, 0x65, 0x47, 0x61, 0x69, 0x6e, 0x20, 0x2a, 0x20, 0x42, 0x69, 0x6e, +0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x47, 0x6f, 0x75, 0x74, 0x20, 0x3d, +0x20, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x52, 0x65, 0x64, 0x47, 0x61, 0x69, 0x6e, 0x20, 0x2a, 0x20, +0x52, 0x69, 0x6e, 0x20, 0x2b, 0x20, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x47, 0x72, 0x65, 0x65, 0x6e, +0x47, 0x61, 0x69, 0x6e, 0x20, 0x2a, 0x20, 0x47, 0x69, 0x6e, 0x20, 0x2b, 0x20, 0x47, 0x72, 0x65, +0x65, 0x6e, 0x42, 0x6c, 0x75, 0x65, 0x47, 0x61, 0x69, 0x6e, 0x20, 0x2a, 0x20, 0x42, 0x69, 0x6e, +0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x42, 0x6f, 0x75, 0x74, 0x20, 0x3d, +0x20, 0x42, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x64, 0x47, 0x61, 0x69, 0x6e, 0x20, 0x2a, 0x20, 0x52, +0x69, 0x6e, 0x20, 0x2b, 0x20, 0x42, 0x6c, 0x75, 0x65, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x47, 0x61, +0x69, 0x6e, 0x20, 0x2a, 0x20, 0x47, 0x69, 0x6e, 0x20, 0x2b, 0x20, 0x42, 0x6c, 0x75, 0x65, 0x42, +0x6c, 0x75, 0x65, 0x47, 0x61, 0x69, 0x6e, 0x20, 0x2a, 0x20, 0x42, 0x69, 0x6e, 0x0a, 0x20, 0x20, +0x20, 0x20, 0x20, 0x2a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x57, 0x65, +0x20, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x47, +0x50, 0x55, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, +0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x6c, 0x55, 0x6e, 0x69, 0x66, 0x6f, +0x72, 0x6d, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x33, 0x66, 0x28, 0x2e, 0x2e, 0x2c, 0x20, 0x2e, +0x2e, 0x2c, 0x20, 0x47, 0x4c, 0x5f, 0x46, 0x41, 0x4c, 0x53, 0x45, 0x2c, 0x20, 0x63, 0x63, 0x6d, +0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2a, +0x20, 0x20, 0x20, 0x43, 0x50, 0x55, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x20, 0x20, +0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x63, 0x63, 0x6d, 0x20, 0x5b, 0x5d, 0x20, 0x3d, 0x20, 0x7b, +0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x64, 0x52, 0x65, 0x64, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x20, +0x20, 0x20, 0x52, 0x65, 0x64, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x20, +0x20, 0x20, 0x52, 0x65, 0x64, 0x42, 0x6c, 0x75, 0x65, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x0a, 0x20, +0x20, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x52, 0x65, 0x64, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x20, +0x47, 0x72, 0x65, 0x65, 0x6e, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x20, +0x47, 0x72, 0x65, 0x65, 0x6e, 0x42, 0x6c, 0x75, 0x65, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x0a, 0x20, +0x20, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x42, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x64, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x20, 0x20, +0x42, 0x6c, 0x75, 0x65, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x20, 0x20, +0x42, 0x6c, 0x75, 0x65, 0x42, 0x6c, 0x75, 0x65, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x0a, 0x20, 0x20, +0x20, 0x20, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x7d, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2a, +0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x47, 0x50, 0x55, 0x0a, 0x20, 0x20, +0x20, 0x20, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x63, 0x63, 0x6d, 0x20, 0x3d, 0x20, 0x7b, 0x0a, 0x20, +0x20, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x52, 0x65, 0x64, 0x52, 0x65, 0x64, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x20, 0x20, 0x20, +0x47, 0x72, 0x65, 0x65, 0x6e, 0x52, 0x65, 0x64, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x20, 0x20, 0x20, +0x42, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x64, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x0a, 0x20, 0x20, 0x20, +0x20, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x52, 0x65, 0x64, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x20, 0x47, 0x72, +0x65, 0x65, 0x6e, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x20, 0x42, 0x6c, +0x75, 0x65, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x0a, 0x20, 0x20, 0x20, +0x20, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x52, 0x65, 0x64, 0x42, 0x6c, 0x75, 0x65, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x20, 0x20, 0x47, 0x72, +0x65, 0x65, 0x6e, 0x42, 0x6c, 0x75, 0x65, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x20, 0x20, 0x42, 0x6c, +0x75, 0x65, 0x42, 0x6c, 0x75, 0x65, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, +0x20, 0x2a, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2a, 0x0a, 0x20, 0x20, +0x20, 0x20, 0x20, 0x2a, 0x20, 0x20, 0x20, 0x48, 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x20, 0x74, +0x68, 0x65, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x6f, 0x72, 0x20, +0x74, 0x68, 0x65, 0x20, 0x6d, 0x61, 0x74, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x74, 0x79, 0x70, +0x65, 0x20, 0x69, 0x73, 0x20, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x20, 0x6d, 0x61, 0x6a, 0x6f, +0x72, 0x20, 0x68, 0x65, 0x6e, 0x63, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x20, +0x20, 0x63, 0x63, 0x6d, 0x5b, 0x30, 0x5d, 0x5b, 0x30, 0x5d, 0x20, 0x3d, 0x20, 0x52, 0x65, 0x64, +0x52, 0x65, 0x64, 0x47, 0x61, 0x69, 0x6e, 0x2c, 0x20, 0x63, 0x63, 0x6d, 0x5b, 0x30, 0x5d, 0x5b, +0x31, 0x5d, 0x20, 0x3d, 0x20, 0x52, 0x65, 0x64, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x47, 0x61, 0x69, +0x6e, 0x2c, 0x20, 0x63, 0x63, 0x6d, 0x5b, 0x30, 0x5d, 0x5b, 0x32, 0x5d, 0x20, 0x3d, 0x20, 0x52, +0x65, 0x64, 0x42, 0x6c, 0x75, 0x65, 0x47, 0x61, 0x69, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, +0x2a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2a, 0x2f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, +0x6f, 0x61, 0x74, 0x20, 0x72, 0x69, 0x6e, 0x2c, 0x20, 0x67, 0x69, 0x6e, 0x2c, 0x20, 0x62, 0x69, +0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x72, 0x67, 0x62, +0x2e, 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x67, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x72, 0x67, +0x62, 0x2e, 0x67, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x62, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x72, +0x67, 0x62, 0x2e, 0x62, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x67, 0x62, 0x2e, 0x72, +0x20, 0x3d, 0x20, 0x28, 0x72, 0x69, 0x6e, 0x20, 0x2a, 0x20, 0x63, 0x63, 0x6d, 0x5b, 0x30, 0x5d, +0x5b, 0x30, 0x5d, 0x29, 0x20, 0x2b, 0x20, 0x28, 0x67, 0x69, 0x6e, 0x20, 0x2a, 0x20, 0x63, 0x63, +0x6d, 0x5b, 0x30, 0x5d, 0x5b, 0x31, 0x5d, 0x29, 0x20, 0x2b, 0x20, 0x28, 0x62, 0x69, 0x6e, 0x20, +0x2a, 0x20, 0x63, 0x63, 0x6d, 0x5b, 0x30, 0x5d, 0x5b, 0x32, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, +0x20, 0x20, 0x72, 0x67, 0x62, 0x2e, 0x67, 0x20, 0x3d, 0x20, 0x28, 0x72, 0x69, 0x6e, 0x20, 0x2a, +0x20, 0x63, 0x63, 0x6d, 0x5b, 0x31, 0x5d, 0x5b, 0x30, 0x5d, 0x29, 0x20, 0x2b, 0x20, 0x28, 0x67, +0x69, 0x6e, 0x20, 0x2a, 0x20, 0x63, 0x63, 0x6d, 0x5b, 0x31, 0x5d, 0x5b, 0x31, 0x5d, 0x29, 0x20, +0x2b, 0x20, 0x28, 0x62, 0x69, 0x6e, 0x20, 0x2a, 0x20, 0x63, 0x63, 0x6d, 0x5b, 0x31, 0x5d, 0x5b, +0x32, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x67, 0x62, 0x2e, 0x62, 0x20, 0x3d, +0x20, 0x28, 0x72, 0x69, 0x6e, 0x20, 0x2a, 0x20, 0x63, 0x63, 0x6d, 0x5b, 0x32, 0x5d, 0x5b, 0x30, +0x5d, 0x29, 0x20, 0x2b, 0x20, 0x28, 0x67, 0x69, 0x6e, 0x20, 0x2a, 0x20, 0x63, 0x63, 0x6d, 0x5b, +0x32, 0x5d, 0x5b, 0x31, 0x5d, 0x29, 0x20, 0x2b, 0x20, 0x28, 0x62, 0x69, 0x6e, 0x20, 0x2a, 0x20, +0x63, 0x63, 0x6d, 0x5b, 0x32, 0x5d, 0x5b, 0x32, 0x5d, 0x29, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, +0x20, 0x2f, 0x2a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72, +0x61, 0x73, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2a, 0x2f, 0x0a, 0x20, 0x20, 0x20, 0x20, +0x72, 0x67, 0x62, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x28, 0x72, 0x67, 0x62, 0x2c, +0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, +0x72, 0x67, 0x62, 0x2e, 0x72, 0x20, 0x3d, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x5f, 0x63, 0x6f, +0x6e, 0x74, 0x72, 0x61, 0x73, 0x74, 0x28, 0x72, 0x67, 0x62, 0x2e, 0x72, 0x29, 0x3b, 0x0a, 0x20, +0x20, 0x20, 0x20, 0x72, 0x67, 0x62, 0x2e, 0x67, 0x20, 0x3d, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, +0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x73, 0x74, 0x28, 0x72, 0x67, 0x62, 0x2e, 0x67, 0x29, +0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x67, 0x62, 0x2e, 0x62, 0x20, 0x3d, 0x20, 0x61, 0x70, +0x70, 0x6c, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x73, 0x74, 0x28, 0x72, 0x67, 0x62, +0x2e, 0x62, 0x29, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2a, 0x20, 0x41, 0x70, 0x70, +0x6c, 0x79, 0x20, 0x67, 0x61, 0x6d, 0x6d, 0x61, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x63, +0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, +0x20, 0x2a, 0x2f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x67, 0x62, 0x20, 0x3d, 0x20, 0x70, 0x6f, +0x77, 0x28, 0x72, 0x67, 0x62, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x67, 0x61, 0x6d, 0x6d, +0x61, 0x29, 0x29, 0x3b, 0x0a, 0x0a, 0x23, 0x69, 0x66, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, +0x64, 0x20, 0x28, 0x53, 0x57, 0x41, 0x50, 0x5f, 0x42, 0x4c, 0x55, 0x45, 0x29, 0x0a, 0x20, 0x20, +0x20, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, +0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x72, 0x67, 0x62, 0x2e, 0x62, 0x67, 0x72, 0x2c, 0x20, 0x31, +0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x23, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x67, +0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x76, 0x65, +0x63, 0x34, 0x28, 0x72, 0x67, 0x62, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x23, 0x65, +0x6e, 0x64, 0x69, 0x66, 0x0a, 0x7d, 0x0a, +}; + +const unsigned int bayer_unpacked_frag_len=6215; + +unsigned char const bayer_unpacked_vert [] = { +0x2f, 0x2a, 0x20, 0x53, 0x50, 0x44, 0x58, 0x2d, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x2d, +0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x3a, 0x20, 0x42, 0x53, 0x44, 0x2d, +0x32, 0x2d, 0x43, 0x6c, 0x61, 0x75, 0x73, 0x65, 0x20, 0x2a, 0x2f, 0x0a, 0x2f, 0x2a, 0x0a, 0x46, +0x72, 0x6f, 0x6d, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6a, 0x67, 0x74, 0x2e, 0x61, +0x6b, 0x70, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x61, 0x70, 0x65, +0x72, 0x73, 0x2f, 0x4d, 0x63, 0x47, 0x75, 0x69, 0x72, 0x65, 0x30, 0x38, 0x2f, 0x0a, 0x0a, 0x45, +0x66, 0x66, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x2c, 0x20, 0x48, 0x69, 0x67, 0x68, 0x2d, 0x51, +0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x20, 0x42, 0x61, 0x79, 0x65, 0x72, 0x20, 0x44, 0x65, 0x6d, +0x6f, 0x73, 0x61, 0x69, 0x63, 0x20, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x20, +0x6f, 0x6e, 0x20, 0x47, 0x50, 0x55, 0x73, 0x0a, 0x0a, 0x4d, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x20, +0x4d, 0x63, 0x47, 0x75, 0x69, 0x72, 0x65, 0x0a, 0x0a, 0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x61, +0x70, 0x65, 0x72, 0x20, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x69, +0x73, 0x73, 0x75, 0x65, 0x20, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x20, 0x31, 0x33, 0x2c, 0x20, +0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x34, 0x2e, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, +0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, +0x2d, 0x2d, 0x2d, 0x0a, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, +0x29, 0x20, 0x32, 0x30, 0x30, 0x38, 0x2c, 0x20, 0x4d, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x20, 0x4d, +0x63, 0x47, 0x75, 0x69, 0x72, 0x65, 0x2e, 0x20, 0x41, 0x6c, 0x6c, 0x20, 0x72, 0x69, 0x67, 0x68, +0x74, 0x73, 0x20, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x4d, 0x6f, +0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x4c, 0x69, 0x6e, 0x61, 0x72, 0x6f, +0x20, 0x4c, 0x74, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, +0x65, 0x20, 0x69, 0x74, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x6c, 0x69, 0x62, 0x63, 0x61, 0x6d, +0x65, 0x72, 0x61, 0x2e, 0x0a, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, +0x43, 0x29, 0x20, 0x32, 0x30, 0x32, 0x31, 0x2c, 0x20, 0x4c, 0x69, 0x6e, 0x61, 0x72, 0x6f, 0x0a, +0x2a, 0x2f, 0x0a, 0x0a, 0x2f, 0x2f, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x20, 0x53, 0x68, 0x61, +0x64, 0x65, 0x72, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x76, +0x65, 0x63, 0x34, 0x20, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x49, 0x6e, 0x3b, 0x0a, 0x61, 0x74, +0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, 0x65, 0x78, +0x74, 0x75, 0x72, 0x65, 0x49, 0x6e, 0x3b, 0x0a, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, +0x20, 0x6d, 0x61, 0x74, 0x34, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x5f, 0x6d, 0x61, 0x74, 0x72, 0x69, +0x78, 0x3b, 0x0a, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x76, 0x65, 0x63, 0x32, +0x20, 0x74, 0x65, 0x78, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x3b, 0x20, 0x20, 0x2f, 0x2a, 0x20, 0x54, +0x68, 0x65, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x20, +0x69, 0x6e, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x73, 0x20, 0x2a, 0x2f, 0x0a, 0x75, 0x6e, 0x69, +0x66, 0x6f, 0x72, 0x6d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, 0x65, 0x78, 0x5f, 0x73, 0x74, +0x65, 0x70, 0x3b, 0x0a, 0x0a, 0x2f, 0x2a, 0x2a, 0x20, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x70, +0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, +0x69, 0x72, 0x73, 0x74, 0x20, 0x72, 0x65, 0x64, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x69, +0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x2a, 0x2f, 0x0a, 0x2f, 0x2a, 0x2a, 0x20, 0x20, 0x42, 0x61, +0x79, 0x65, 0x72, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x2e, 0x20, 0x20, 0x5b, 0x7b, +0x30, 0x2c, 0x31, 0x7d, 0x2c, 0x20, 0x7b, 0x30, 0x2c, 0x20, 0x31, 0x7d, 0x5d, 0x2a, 0x2f, 0x0a, +0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x5f, 0x62, 0x61, 0x79, 0x65, +0x72, 0x5f, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x64, 0x3b, 0x0a, 0x0a, 0x2f, 0x2a, +0x2a, 0x20, 0x2e, 0x78, 0x79, 0x20, 0x3d, 0x20, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x62, 0x65, +0x69, 0x6e, 0x67, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, +0x68, 0x65, 0x20, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x73, 0x68, 0x61, 0x64, +0x65, 0x72, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x20, +0x5b, 0x30, 0x2c, 0x20, 0x31, 0x5d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2e, 0x7a, 0x77, 0x20, 0x3d, +0x20, 0x2e, 0x2e, 0x2e, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65, +0x20, 0x5b, 0x30, 0x2c, 0x20, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x5d, +0x2c, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x20, 0x62, 0x79, 0x20, 0x66, 0x69, 0x72, 0x73, +0x74, 0x52, 0x65, 0x64, 0x20, 0x2a, 0x2f, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, +0x76, 0x65, 0x63, 0x34, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0x0a, 0x0a, 0x2f, 0x2a, 0x2a, 0x20, 0x63, 0x65, 0x6e, +0x74, 0x65, 0x72, 0x2e, 0x78, 0x20, 0x2b, 0x20, 0x28, 0x2d, 0x32, 0x2f, 0x77, 0x2c, 0x20, 0x2d, +0x31, 0x2f, 0x77, 0x2c, 0x20, 0x31, 0x2f, 0x77, 0x2c, 0x20, 0x32, 0x2f, 0x77, 0x29, 0x3b, 0x20, +0x54, 0x68, 0x65, 0x73, 0x65, 0x20, 0x61, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x78, 0x2d, +0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x2a, 0x2f, 0x0a, 0x2f, 0x2a, 0x2a, +0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x64, 0x6a, 0x61, 0x63, 0x65, 0x6e, 0x74, +0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x73, 0x2e, 0x2a, 0x2f, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, +0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x0a, 0x2f, 0x2a, 0x2a, 0x20, +0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x79, 0x20, 0x2b, 0x20, 0x28, 0x2d, 0x32, 0x2f, 0x68, +0x2c, 0x20, 0x2d, 0x31, 0x2f, 0x68, 0x2c, 0x20, 0x31, 0x2f, 0x68, 0x2c, 0x20, 0x32, 0x2f, 0x68, +0x29, 0x3b, 0x20, 0x54, 0x68, 0x65, 0x73, 0x65, 0x20, 0x61, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, +0x20, 0x79, 0x2d, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x2a, 0x2f, 0x0a, +0x2f, 0x2a, 0x2a, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x64, 0x6a, 0x61, 0x63, +0x65, 0x6e, 0x74, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x73, 0x2e, 0x2a, 0x2f, 0x0a, 0x76, 0x61, +0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x79, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x0a, 0x75, +0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x73, 0x74, 0x72, +0x69, 0x64, 0x65, 0x5f, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x3b, 0x0a, 0x0a, 0x76, 0x6f, 0x69, +0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x76, 0x6f, 0x69, 0x64, 0x29, 0x20, 0x7b, 0x0a, 0x20, +0x20, 0x20, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x78, 0x79, 0x20, 0x3d, 0x20, 0x76, +0x65, 0x63, 0x32, 0x28, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x49, 0x6e, 0x2e, 0x78, 0x20, +0x2a, 0x20, 0x73, 0x74, 0x72, 0x69, 0x64, 0x65, 0x5f, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x2c, +0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x49, 0x6e, 0x2e, 0x79, 0x29, 0x3b, 0x0a, 0x20, +0x20, 0x20, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x7a, 0x77, 0x20, 0x3d, 0x20, 0x74, +0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x49, 0x6e, 0x20, 0x2a, 0x20, 0x74, 0x65, 0x78, 0x5f, 0x73, +0x69, 0x7a, 0x65, 0x20, 0x2b, 0x20, 0x74, 0x65, 0x78, 0x5f, 0x62, 0x61, 0x79, 0x65, 0x72, 0x5f, +0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x64, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, +0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x20, 0x3d, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, +0x78, 0x20, 0x2b, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x2d, 0x32, 0x2e, 0x30, 0x20, 0x2a, 0x20, +0x74, 0x65, 0x78, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x2e, 0x78, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x74, 0x65, 0x78, 0x5f, 0x73, 0x74, +0x65, 0x70, 0x2e, 0x78, 0x2c, 0x20, 0x74, 0x65, 0x78, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x2e, 0x78, +0x2c, 0x20, 0x32, 0x2e, 0x30, 0x20, 0x2a, 0x20, 0x74, 0x65, 0x78, 0x5f, 0x73, 0x74, 0x65, 0x70, +0x2e, 0x78, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x79, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x20, +0x3d, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x79, 0x20, 0x2b, 0x20, 0x76, 0x65, 0x63, +0x34, 0x28, 0x2d, 0x32, 0x2e, 0x30, 0x20, 0x2a, 0x20, 0x74, 0x65, 0x78, 0x5f, 0x73, 0x74, 0x65, +0x70, 0x2e, 0x79, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x2d, 0x74, 0x65, 0x78, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x2e, 0x79, 0x2c, 0x20, +0x74, 0x65, 0x78, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x2e, 0x79, 0x2c, 0x20, 0x32, 0x2e, 0x30, 0x20, +0x2a, 0x20, 0x74, 0x65, 0x78, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x2e, 0x79, 0x29, 0x3b, 0x0a, 0x0a, +0x20, 0x20, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, +0x3d, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x5f, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x2a, 0x20, +0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x49, 0x6e, 0x3b, 0x0a, 0x7d, 0x0a, +}; + +const unsigned int bayer_unpacked_vert_len=1628; + +unsigned char const identity_vert [] = { +0x2f, 0x2a, 0x20, 0x53, 0x50, 0x44, 0x58, 0x2d, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x2d, +0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x3a, 0x20, 0x4c, 0x47, 0x50, 0x4c, +0x2d, 0x32, 0x2e, 0x31, 0x2d, 0x6f, 0x72, 0x2d, 0x6c, 0x61, 0x74, 0x65, 0x72, 0x20, 0x2a, 0x2f, +0x0a, 0x2f, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, +0x20, 0x28, 0x43, 0x29, 0x20, 0x32, 0x30, 0x32, 0x30, 0x2c, 0x20, 0x4c, 0x69, 0x6e, 0x61, 0x72, +0x6f, 0x0a, 0x20, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, +0x2e, 0x76, 0x65, 0x72, 0x74, 0x20, 0x2d, 0x20, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, +0x20, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x20, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x66, +0x6f, 0x72, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, +0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x2a, 0x2f, 0x0a, 0x0a, +0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x76, +0x65, 0x72, 0x74, 0x65, 0x78, 0x49, 0x6e, 0x3b, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, +0x74, 0x65, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x49, +0x6e, 0x3b, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, +0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x4f, 0x75, 0x74, 0x3b, 0x0a, 0x0a, 0x75, 0x6e, 0x69, +0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x5f, 0x6d, +0x61, 0x74, 0x72, 0x69, 0x78, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x66, +0x6c, 0x6f, 0x61, 0x74, 0x20, 0x73, 0x74, 0x72, 0x69, 0x64, 0x65, 0x5f, 0x66, 0x61, 0x63, 0x74, +0x6f, 0x72, 0x3b, 0x0a, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x76, +0x6f, 0x69, 0x64, 0x29, 0x0a, 0x7b, 0x0a, 0x09, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, +0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x5f, 0x6d, 0x61, 0x74, 0x72, 0x69, +0x78, 0x20, 0x2a, 0x20, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x49, 0x6e, 0x3b, 0x0a, 0x09, 0x74, +0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x4f, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x32, +0x28, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x49, 0x6e, 0x2e, 0x78, 0x20, 0x2a, 0x20, 0x73, +0x74, 0x72, 0x69, 0x64, 0x65, 0x5f, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x2c, 0x20, 0x74, 0x65, +0x78, 0x74, 0x75, 0x72, 0x65, 0x49, 0x6e, 0x2e, 0x79, 0x29, 0x3b, 0x0a, 0x7d, 0x0a, +}; + +const unsigned int identity_vert_len=414; + diff --git a/meson_generated/src/libcamera/ipa_pub_key.cpp b/meson_generated/src/libcamera/ipa_pub_key.cpp new file mode 100644 index 00000000..51db238c --- /dev/null +++ b/meson_generated/src/libcamera/ipa_pub_key.cpp @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Laurent Pinchart + * + * IPA module signing public key + * + * This file is auto-generated. Do not edit. + */ + +#include "libcamera/internal/ipa_manager.h" + +namespace libcamera { + +#if HAVE_IPA_PUBKEY +const uint8_t IPAManager::publicKeyData_[] = { + 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, + 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, + 0x00, 0xb2, 0x52, 0x0d, 0x72, 0xd0, 0xd1, 0xdd, + 0x52, 0x55, 0xfe, 0x69, 0x6e, 0x08, 0x3b, 0x67, + 0x4c, 0x52, 0xb4, 0x69, 0x8b, 0x4c, 0x68, 0xac, + 0x84, 0xc9, 0xa7, 0x94, 0xf4, 0xfe, 0x1e, 0xe5, + 0x56, 0x30, 0xad, 0x9e, 0x72, 0xd6, 0x7c, 0x45, + 0x1b, 0x96, 0x21, 0xa7, 0xae, 0x64, 0x73, 0x05, + 0x3b, 0x5d, 0x7c, 0x9a, 0x5f, 0xab, 0x8c, 0xca, + 0x04, 0x65, 0x6b, 0xe2, 0xe2, 0x57, 0x39, 0xec, + 0x54, 0xde, 0x46, 0x0f, 0x29, 0x64, 0xa1, 0x2d, + 0xe4, 0xcf, 0x34, 0x85, 0x79, 0xc4, 0xe6, 0x4b, + 0x2e, 0x8e, 0x30, 0x97, 0x48, 0x9d, 0xef, 0x05, + 0xe1, 0x52, 0x3d, 0x76, 0x19, 0xc4, 0xd0, 0xfb, + 0x26, 0xe7, 0xc2, 0x6f, 0xbf, 0xa9, 0xd7, 0x7a, + 0x78, 0x19, 0x76, 0xd9, 0xa9, 0x5d, 0x89, 0xcf, + 0x7e, 0x1c, 0xc1, 0xfb, 0x08, 0x7e, 0x65, 0xee, + 0xa5, 0xfe, 0x24, 0x08, 0xab, 0xb4, 0x56, 0x55, + 0x47, 0x64, 0x7e, 0xea, 0xd1, 0xba, 0x1e, 0xb8, + 0x7d, 0x9e, 0x8f, 0xa3, 0x1c, 0xd1, 0x01, 0xd7, + 0x59, 0xfd, 0x7d, 0x05, 0x22, 0x05, 0x6b, 0x22, + 0x22, 0xa4, 0x8a, 0x52, 0xd1, 0xe9, 0x45, 0xa8, + 0xbf, 0xf2, 0xab, 0x0a, 0x4f, 0xed, 0x28, 0x19, + 0xdf, 0xb7, 0x64, 0x59, 0x44, 0x8b, 0xb4, 0x82, + 0x8d, 0xc7, 0xd3, 0x28, 0xd3, 0x42, 0x3d, 0x86, + 0xd7, 0xb5, 0x65, 0x04, 0xf0, 0x3a, 0x1a, 0x63, + 0x3f, 0x4a, 0x40, 0xf6, 0x02, 0xd6, 0xcf, 0x9f, + 0x53, 0x91, 0x1f, 0xd2, 0x4c, 0xab, 0xee, 0xce, + 0xd5, 0xf6, 0xcf, 0x3f, 0x02, 0xac, 0x69, 0x79, + 0x82, 0x02, 0x53, 0x54, 0xa8, 0x7b, 0x7f, 0xe6, + 0xfe, 0x1d, 0x8d, 0xfb, 0x4e, 0x51, 0x8b, 0x14, + 0xb9, 0x21, 0xa7, 0x35, 0xa4, 0xff, 0x2e, 0x6b, + 0x3d, 0xd8, 0xd3, 0x92, 0x16, 0x81, 0x3f, 0xd4, + 0x6d, 0x6d, 0x47, 0x6e, 0xa7, 0x43, 0xda, 0x19, + 0xc5, 0x02, 0x03, 0x01, 0x00, 0x01 +}; + +const PubKey IPAManager::pubKey_{ { IPAManager::publicKeyData_ } }; +#endif + +} /* namespace libcamera */ diff --git a/meson_generated/src/libcamera/property_ids.cpp b/meson_generated/src/libcamera/property_ids.cpp new file mode 100644 index 00000000..1b16dca5 --- /dev/null +++ b/meson_generated/src/libcamera/property_ids.cpp @@ -0,0 +1,872 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * properties ID list + * + * This file is auto-generated. Do not edit. + */ + +#include +#include + +/** + * \file property_ids.h + * \brief Camera properties identifiers + */ + +namespace libcamera { + +/** + * \brief Namespace for libcamera properties + */ +namespace properties { + +/** + * \enum LocationEnum + * \brief Supported Location values + * + * \var CameraLocationFront + * \brief The camera is mounted on the front side of the device, facing the + * user + * + * \var CameraLocationBack + * \brief The camera is mounted on the back side of the device, facing away + * from the user + * + * \var CameraLocationExternal + * \brief The camera is attached to the device in a way that allows it to + * be moved freely + */ + +/** + * \var LocationValues + * \brief List of all Location supported values + */ + +/** + * \var LocationNameValueMap + * \brief Map of all Location supported value names (in std::string format) to value + */ + +/** + * \var Location + * \brief Camera mounting location + */ + +/** + * \var Rotation + * \brief The camera physical mounting rotation. It is expressed as the angular + * difference in degrees between two reference systems, one relative to the + * camera module, and one defined on the external world scene to be + * captured when projected on the image sensor pixel array. + * + * A camera sensor has a 2-dimensional reference system 'Rc' defined by + * its pixel array read-out order. The origin is set to the first pixel + * being read out, the X-axis points along the column read-out direction + * towards the last columns, and the Y-axis along the row read-out + * direction towards the last row. + * + * A typical example for a sensor with a 2592x1944 pixel array matrix + * observed from the front is + * + * 2591 X-axis 0 + * <------------------------+ 0 + * .......... ... ..........! + * .......... ... ..........! Y-axis + * ... ! + * .......... ... ..........! + * .......... ... ..........! 1943 + * V + * + * + * The external world scene reference system 'Rs' is a 2-dimensional + * reference system on the focal plane of the camera module. The origin is + * placed on the top-left corner of the visible scene, the X-axis points + * towards the right, and the Y-axis points towards the bottom of the + * scene. The top, bottom, left and right directions are intentionally not + * defined and depend on the environment in which the camera is used. + * + * A typical example of a (very common) picture of a shark swimming from + * left to right, as seen from the camera, is + * + * 0 X-axis + * 0 +-------------------------------------> + * ! + * ! + * ! + * ! |\____)\___ + * ! ) _____ __`< + * ! |/ )/ + * ! + * ! + * ! + * V + * Y-axis + * + * With the reference system 'Rs' placed on the camera focal plane. + * + * ¸.·˙! + * ¸.·˙ ! + * _ ¸.·˙ ! + * +-/ \-+¸.·˙ ! + * | (o) | ! Camera focal plane + * +-----+˙·.¸ ! + * ˙·.¸ ! + * ˙·.¸ ! + * ˙·.¸! + * + * When projected on the sensor's pixel array, the image and the associated + * reference system 'Rs' are typically (but not always) inverted, due to + * the camera module's lens optical inversion effect. + * + * Assuming the above represented scene of the swimming shark, the lens + * inversion projects the scene and its reference system onto the sensor + * pixel array, seen from the front of the camera sensor, as follow + * + * Y-axis + * ^ + * ! + * ! + * ! + * ! |\_____)\__ + * ! ) ____ ___.< + * ! |/ )/ + * ! + * ! + * ! + * 0 +-------------------------------------> + * 0 X-axis + * + * Note the shark being upside-down. + * + * The resulting projected reference system is named 'Rp'. + * + * The camera rotation property is then defined as the angular difference + * in the counter-clockwise direction between the camera reference system + * 'Rc' and the projected scene reference system 'Rp'. It is expressed in + * degrees as a number in the range [0, 360[. + * + * Examples + * + * 0 degrees camera rotation + * + * + * Y-Rp + * ^ + * Y-Rc ! + * ^ ! + * ! ! + * ! ! + * ! ! + * ! ! + * ! ! + * ! ! + * ! ! + * ! 0 +-------------------------------------> + * ! 0 X-Rp + * 0 +-------------------------------------> + * 0 X-Rc + * + * + * X-Rc 0 + * <------------------------------------+ 0 + * X-Rp 0 ! + * <------------------------------------+ 0 ! + * ! ! + * ! ! + * ! ! + * ! ! + * ! ! + * ! ! + * ! ! + * ! V + * ! Y-Rc + * V + * Y-Rp + * + * 90 degrees camera rotation + * + * 0 Y-Rc + * 0 +--------------------> + * ! Y-Rp + * ! ^ + * ! ! + * ! ! + * ! ! + * ! ! + * ! ! + * ! ! + * ! ! + * ! ! + * ! ! + * ! 0 +-------------------------------------> + * ! 0 X-Rp + * ! + * ! + * ! + * ! + * V + * X-Rc + * + * 180 degrees camera rotation + * + * 0 + * <------------------------------------+ 0 + * X-Rc ! + * Y-Rp ! + * ^ ! + * ! ! + * ! ! + * ! ! + * ! ! + * ! ! + * ! ! + * ! V + * ! Y-Rc + * 0 +-------------------------------------> + * 0 X-Rp + * + * 270 degrees camera rotation + * + * 0 Y-Rc + * 0 +--------------------> + * ! 0 + * ! <-----------------------------------+ 0 + * ! X-Rp ! + * ! ! + * ! ! + * ! ! + * ! ! + * ! ! + * ! ! + * ! ! + * ! ! + * ! V + * ! Y-Rp + * ! + * ! + * ! + * ! + * V + * X-Rc + * + * + * Example one - Webcam + * + * A camera module installed on the user facing part of a laptop screen + * casing used for video calls. The captured images are meant to be + * displayed in landscape mode (width > height) on the laptop screen. + * + * The camera is typically mounted upside-down to compensate the lens + * optical inversion effect. + * + * Y-Rp + * Y-Rc ^ + * ^ ! + * ! ! + * ! ! |\_____)\__ + * ! ! ) ____ ___.< + * ! ! |/ )/ + * ! ! + * ! ! + * ! ! + * ! 0 +-------------------------------------> + * ! 0 X-Rp + * 0 +-------------------------------------> + * 0 X-Rc + * + * The two reference systems are aligned, the resulting camera rotation is + * 0 degrees, no rotation correction needs to be applied to the resulting + * image once captured to memory buffers to correctly display it to users. + * + * +--------------------------------------+ + * ! ! + * ! ! + * ! ! + * ! |\____)\___ ! + * ! ) _____ __`< ! + * ! |/ )/ ! + * ! ! + * ! ! + * ! ! + * +--------------------------------------+ + * + * If the camera sensor is not mounted upside-down to compensate for the + * lens optical inversion, the two reference systems will not be aligned, + * with 'Rp' being rotated 180 degrees relatively to 'Rc'. + * + * + * X-Rc 0 + * <------------------------------------+ 0 + * ! + * Y-Rp ! + * ^ ! + * ! ! + * ! |\_____)\__ ! + * ! ) ____ ___.< ! + * ! |/ )/ ! + * ! ! + * ! ! + * ! V + * ! Y-Rc + * 0 +-------------------------------------> + * 0 X-Rp + * + * The image once captured to memory will then be rotated by 180 degrees + * + * +--------------------------------------+ + * ! ! + * ! ! + * ! ! + * ! __/(_____/| ! + * ! >.___ ____ ( ! + * ! \( \| ! + * ! ! + * ! ! + * ! ! + * +--------------------------------------+ + * + * A software rotation correction of 180 degrees should be applied to + * correctly display the image. + * + * +--------------------------------------+ + * ! ! + * ! ! + * ! ! + * ! |\____)\___ ! + * ! ) _____ __`< ! + * ! |/ )/ ! + * ! ! + * ! ! + * ! ! + * +--------------------------------------+ + * + * Example two - Phone camera + * + * A camera installed on the back side of a mobile device facing away from + * the user. The captured images are meant to be displayed in portrait mode + * (height > width) to match the device screen orientation and the device + * usage orientation used when taking the picture. + * + * The camera sensor is typically mounted with its pixel array longer side + * aligned to the device longer side, upside-down mounted to compensate for + * the lens optical inversion effect. + * + * 0 Y-Rc + * 0 +--------------------> + * ! Y-Rp + * ! ^ + * ! ! + * ! ! + * ! ! + * ! ! |\_____)\__ + * ! ! ) ____ ___.< + * ! ! |/ )/ + * ! ! + * ! ! + * ! ! + * ! 0 +-------------------------------------> + * ! 0 X-Rp + * ! + * ! + * ! + * ! + * V + * X-Rc + * + * The two reference systems are not aligned and the 'Rp' reference + * system is rotated by 90 degrees in the counter-clockwise direction + * relatively to the 'Rc' reference system. + * + * The image once captured to memory will be rotated. + * + * +-------------------------------------+ + * | _ _ | + * | \ / | + * | | | | + * | | | | + * | | > | + * | < | | + * | | | | + * | . | + * | V | + * +-------------------------------------+ + * + * A correction of 90 degrees in counter-clockwise direction has to be + * applied to correctly display the image in portrait mode on the device + * screen. + * + * +--------------------+ + * | | + * | | + * | | + * | | + * | | + * | | + * | |\____)\___ | + * | ) _____ __`< | + * | |/ )/ | + * | | + * | | + * | | + * | | + * | | + * +--------------------+ + */ + +/** + * \var Model + * \brief The model name shall to the extent possible describe the sensor. For + * most devices this is the model name of the sensor. While for some + * devices the sensor model is unavailable as the sensor or the entire + * camera is part of a larger unit and exposed as a black-box to the + * system. In such cases the model name of the smallest device that + * contains the camera sensor shall be used. + * + * The model name is not meant to be a camera name displayed to the + * end-user, but may be combined with other camera information to create a + * camera name. + * + * The model name is not guaranteed to be unique in the system nor is + * it guaranteed to be stable or have any other properties required to make + * it a good candidate to be used as a permanent identifier of a camera. + * + * The model name shall describe the camera in a human readable format and + * shall be encoded in ASCII. + * + * Example model names are 'ov5670', 'imx219' or 'Logitech Webcam C930e'. + */ + +/** + * \var UnitCellSize + * \brief The pixel unit cell physical size, in nanometers. + * + * The UnitCellSize properties defines the horizontal and vertical sizes of + * a single pixel unit, including its active and non-active parts. In + * other words, it expresses the horizontal and vertical distance between + * the top-left corners of adjacent pixels. + * + * The property can be used to calculate the physical size of the sensor's + * pixel array area and for calibration purposes. + */ + +/** + * \var PixelArraySize + * \brief The camera sensor pixel array readable area vertical and horizontal + * sizes, in pixels. + * + * The PixelArraySize property defines the size in pixel units of the + * readable part of full pixel array matrix, including optical black + * pixels used for calibration, pixels which are not considered valid for + * capture and active pixels containing valid image data. + * + * The property describes the maximum size of the raw data captured by the + * camera, which might not correspond to the physical size of the sensor + * pixel array matrix, as some portions of the physical pixel array matrix + * are not accessible and cannot be transmitted out. + * + * For example, let's consider a pixel array matrix assembled as follows + * + * +--------------------------------------------------+ + * |xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx| + * |xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx| + * |xxDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDxx| + * |xxDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDxx| + * |xxDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDxx| + * |xxDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDxx| + * |xxDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDxx| + * |xxDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDxx| + * ... ... ... ... ... + * + * ... ... ... ... ... + * |xxDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDxx| + * |xxDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDxx| + * |xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx| + * |xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx| + * +--------------------------------------------------+ + * + * starting with two lines of non-readable pixels (x), followed by N lines + * of readable data (D) surrounded by two columns of non-readable pixels on + * each side, and ending with two more lines of non-readable pixels. Only + * the readable portion is transmitted to the receiving side, defining the + * sizes of the largest possible buffer of raw data that can be presented + * to applications. + * + * PixelArraySize.width + * /----------------------------------------------/ + * +----------------------------------------------+ / + * |DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD| | + * |DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD| | + * |DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD| | + * |DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD| | + * |DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD| | + * |DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD| | PixelArraySize.height + * ... ... ... ... ... + * ... ... ... ... ... + * |DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD| | + * |DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD| | + * +----------------------------------------------+ / + * + * This defines a rectangle whose top-left corner is placed in position (0, + * 0) and whose vertical and horizontal sizes are defined by this property. + * All other rectangles that describe portions of the pixel array, such as + * the optical black pixels rectangles and active pixel areas, are defined + * relatively to this rectangle. + * + * All the coordinates are expressed relative to the default sensor readout + * direction, without any transformation (such as horizontal and vertical + * flipping) applied. When mapping them to the raw pixel buffer, + * applications shall take any configured transformation into account. + * + * \todo Rename this property to Size once we will have property + * categories (i.e. Properties::PixelArray::Size) + */ + +/** + * \var PixelArrayOpticalBlackRectangles + * \brief The pixel array region(s) which contain optical black pixels + * considered valid for calibration purposes. + * + * This property describes the position and size of optical black pixel + * regions in the raw data buffer as stored in memory, which might differ + * from their actual physical location in the pixel array matrix. + * + * It is important to note, in fact, that camera sensors might + * automatically reorder or skip portions of their pixels array matrix when + * transmitting data to the receiver. For instance, a sensor may merge the + * top and bottom optical black rectangles into a single rectangle, + * transmitted at the beginning of the frame. + * + * The pixel array contains several areas with different purposes, + * interleaved by lines and columns which are said not to be valid for + * capturing purposes. Invalid lines and columns are defined as invalid as + * they could be positioned too close to the chip margins or to the optical + * black shielding placed on top of optical black pixels. + * + * PixelArraySize.width + * /----------------------------------------------/ + * x1 x2 + * +--o---------------------------------------o---+ / + * |IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII| | + * |IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII| | + * y1 oIIOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOII| | + * |IIOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOII| | + * |IIOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOII| | + * y2 oIIOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOII| | + * |IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII| | + * |IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII| | + * y3 |IIOOPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPOOII| | + * |IIOOPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPOOII| | PixelArraySize.height + * |IIOOPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPOOII| | + * ... ... ... ... ... + * ... ... ... ... ... + * y4 |IIOOPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPOOII| | + * |IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII| | + * |IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII| | + * +----------------------------------------------+ / + * + * The readable pixel array matrix is composed by + * 2 invalid lines (I) + * 4 lines of valid optical black pixels (O) + * 2 invalid lines (I) + * n lines of valid pixel data (P) + * 2 invalid lines (I) + * + * And the position of the optical black pixel rectangles is defined by + * + * PixelArrayOpticalBlackRectangles = { + * { x1, y1, x2 - x1 + 1, y2 - y1 + 1 }, + * { x1, y3, 2, y4 - y3 + 1 }, + * { x2, y3, 2, y4 - y3 + 1 }, + * }; + * + * If the camera, when capturing the full pixel array matrix, automatically + * skips the invalid lines and columns, producing the following data + * buffer, when captured to memory + * + * PixelArraySize.width + * /----------------------------------------------/ + * x1 + * +--------------------------------------------o-+ / + * |OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO| | + * |OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO| | + * |OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO| | + * |OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO| | + * y1 oOOPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPOO| | + * |OOPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPOO| | + * |OOPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPOO| | PixelArraySize.height + * ... ... ... ... ... | + * ... ... ... ... ... | + * |OOPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPOO| | + * |OOPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPOO| | + * +----------------------------------------------+ / + * + * then the invalid lines and columns should not be reported as part of the + * PixelArraySize property in first place. + * + * In this case, the position of the black pixel rectangles will be + * + * PixelArrayOpticalBlackRectangles = { + * { 0, 0, y1 + 1, PixelArraySize[0] }, + * { 0, y1, 2, PixelArraySize[1] - y1 + 1 }, + * { x1, y1, 2, PixelArraySize[1] - y1 + 1 }, + * }; + * + * \todo Rename this property to Size once we will have property + * categories (i.e. Properties::PixelArray::OpticalBlackRectangles) + */ + +/** + * \var PixelArrayActiveAreas + * \brief The PixelArrayActiveAreas property defines the (possibly multiple and + * overlapping) portions of the camera sensor readable pixel matrix + * which are considered valid for image acquisition purposes. + * + * This property describes an arbitrary number of overlapping rectangles, + * with each rectangle representing the maximum image size that the camera + * sensor can produce for a particular aspect ratio. They are defined + * relatively to the PixelArraySize rectangle. + * + * When multiple rectangles are reported, they shall be ordered from the + * tallest to the shortest. + * + * Example 1 + * A camera sensor which only produces images in the 4:3 image resolution + * will report a single PixelArrayActiveAreas rectangle, from which all + * other image formats are obtained by either cropping the field-of-view + * and/or applying pixel sub-sampling techniques such as pixel skipping or + * binning. + * + * PixelArraySize.width + * /----------------/ + * x1 x2 + * (0,0)-> +-o------------o-+ / + * y1 o +------------+ | | + * | |////////////| | | + * | |////////////| | | PixelArraySize.height + * | |////////////| | | + * y2 o +------------+ | | + * +----------------+ / + * + * The property reports a single rectangle + * + * PixelArrayActiveAreas = (x1, y1, x2 - x1 + 1, y2 - y1 + 1) + * + * Example 2 + * A camera sensor which can produce images in different native + * resolutions will report several overlapping rectangles, one for each + * natively supported resolution. + * + * PixelArraySize.width + * /------------------/ + * x1 x2 x3 x4 + * (0,0)-> +o---o------o---o+ / + * y1 o +------+ | | + * | |//////| | | + * y2 o+---+------+---+| | + * ||///|//////|///|| | PixelArraySize.height + * y3 o+---+------+---+| | + * | |//////| | | + * y4 o +------+ | | + * +----+------+----+ / + * + * The property reports two rectangles + * + * PixelArrayActiveAreas = ((x2, y1, x3 - x2 + 1, y4 - y1 + 1), + * (x1, y2, x4 - x1 + 1, y3 - y2 + 1)) + * + * The first rectangle describes the maximum field-of-view of all image + * formats in the 4:3 resolutions, while the second one describes the + * maximum field of view for all image formats in the 16:9 resolutions. + * + * Multiple rectangles shall only be reported when the sensor can't capture + * the pixels in the corner regions. If all the pixels in the (x1,y1) - + * (x4,y4) area can be captured, the PixelArrayActiveAreas property shall + * contains the single rectangle (x1,y1) - (x4,y4). + * + * \todo Rename this property to ActiveAreas once we will have property + * categories (i.e. Properties::PixelArray::ActiveAreas) + */ + +/** + * \var ScalerCropMaximum + * \brief The maximum valid rectangle for the controls::ScalerCrop control. This + * reflects the minimum mandatory cropping applied in the camera sensor and + * the rest of the pipeline. Just as the ScalerCrop control, it defines a + * rectangle taken from the sensor's active pixel array. + * + * This property is valid only after the camera has been successfully + * configured and its value may change whenever a new configuration is + * applied. + * + * \todo Turn this property into a "maximum control value" for the + * ScalerCrop control once "dynamic" controls have been implemented. + */ + +/** + * \var SensorSensitivity + * \brief The relative sensitivity of the chosen sensor mode. + * + * Some sensors have readout modes with different sensitivities. For example, + * a binned camera mode might, with the same exposure and gains, produce + * twice the signal level of the full resolution readout. This would be + * signalled by the binned mode, when it is chosen, indicating a value here + * that is twice that of the full resolution mode. This value will be valid + * after the configure method has returned successfully. + */ + +/** + * \var SystemDevices + * \brief A list of integer values of type dev_t denoting the major and minor + * device numbers of the underlying devices used in the operation of this + * camera. + * + * Different cameras may report identical devices. + */ + +/** + * \var PipelineHandler + * \brief The name of the pipeline handler that manages this camera device.o + * + * This property is meant to help development, debugging and support. The + * pipeline handler name is not guaranteed to be stable across libcamera + * releases. + */ + +/** + * \brief Namespace for draft properties + */ +namespace draft { + +/** + * \enum ColorFilterArrangementEnum + * \brief Supported ColorFilterArrangement values + * + * \var RGGB + * \brief RGGB Bayer pattern + * + * \var GRBG + * \brief GRBG Bayer pattern + * + * \var GBRG + * \brief GBRG Bayer pattern + * + * \var BGGR + * \brief BGGR Bayer pattern + * + * \var RGB + * \brief Sensor is not Bayer; output has 3 16-bit values for each pixel, + * instead of just 1 16-bit value per pixel. + * + * \var MONO + * \brief Sensor is not Bayer; output consists of a single colour channel. + */ + +/** + * \var ColorFilterArrangementValues + * \brief List of all ColorFilterArrangement supported values + */ + +/** + * \var ColorFilterArrangementNameValueMap + * \brief Map of all ColorFilterArrangement supported value names (in std::string format) to value + */ + +/** + * \var ColorFilterArrangement + * \brief The arrangement of color filters on sensor; represents the colors in the + * top-left 2x2 section of the sensor, in reading order. Currently + * identical to ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT. + */ + +} /* namespace draft */ + + +#ifndef __DOXYGEN__ +/* + * Keep the properties definitions hidden from doxygen as it incorrectly parses + * them as functions. + */ + +extern const std::array LocationValues = { + static_cast(CameraLocationFront), + static_cast(CameraLocationBack), + static_cast(CameraLocationExternal), +}; +extern const std::map LocationNameValueMap = { + { "CameraLocationFront", CameraLocationFront }, + { "CameraLocationBack", CameraLocationBack }, + { "CameraLocationExternal", CameraLocationExternal }, +}; +extern const Control Location(LOCATION, "Location", "libcamera", ControlId::Direction::Out, LocationNameValueMap); + +extern const Control Rotation(ROTATION, "Rotation", "libcamera", ControlId::Direction::Out); + +extern const Control Model(MODEL, "Model", "libcamera", ControlId::Direction::Out); + +extern const Control UnitCellSize(UNIT_CELL_SIZE, "UnitCellSize", "libcamera", ControlId::Direction::Out); + +extern const Control PixelArraySize(PIXEL_ARRAY_SIZE, "PixelArraySize", "libcamera", ControlId::Direction::Out); + +extern const Control> PixelArrayOpticalBlackRectangles(PIXEL_ARRAY_OPTICAL_BLACK_RECTANGLES, "PixelArrayOpticalBlackRectangles", "libcamera", ControlId::Direction::Out); + +extern const Control> PixelArrayActiveAreas(PIXEL_ARRAY_ACTIVE_AREAS, "PixelArrayActiveAreas", "libcamera", ControlId::Direction::Out); + +extern const Control ScalerCropMaximum(SCALER_CROP_MAXIMUM, "ScalerCropMaximum", "libcamera", ControlId::Direction::Out); + +extern const Control SensorSensitivity(SENSOR_SENSITIVITY, "SensorSensitivity", "libcamera", ControlId::Direction::Out); + +extern const Control> SystemDevices(SYSTEM_DEVICES, "SystemDevices", "libcamera", ControlId::Direction::Out); + +extern const Control PipelineHandler(PIPELINE_HANDLER, "PipelineHandler", "libcamera", ControlId::Direction::Out); + + + +namespace draft { + +extern const std::array ColorFilterArrangementValues = { + static_cast(RGGB), + static_cast(GRBG), + static_cast(GBRG), + static_cast(BGGR), + static_cast(RGB), + static_cast(MONO), +}; +extern const std::map ColorFilterArrangementNameValueMap = { + { "RGGB", RGGB }, + { "GRBG", GRBG }, + { "GBRG", GBRG }, + { "BGGR", BGGR }, + { "RGB", RGB }, + { "MONO", MONO }, +}; +extern const Control ColorFilterArrangement(COLOR_FILTER_ARRANGEMENT, "ColorFilterArrangement", "draft", ControlId::Direction::Out, ColorFilterArrangementNameValueMap); + + + +} /* namespace draft */ + +#endif /* __DOXYGEN__ */ + +/** + * \brief List of all supported libcamera properties + */ +extern const ControlIdMap properties { + { LOCATION, &Location }, + { ROTATION, &Rotation }, + { MODEL, &Model }, + { UNIT_CELL_SIZE, &UnitCellSize }, + { PIXEL_ARRAY_SIZE, &PixelArraySize }, + { PIXEL_ARRAY_OPTICAL_BLACK_RECTANGLES, &PixelArrayOpticalBlackRectangles }, + { PIXEL_ARRAY_ACTIVE_AREAS, &PixelArrayActiveAreas }, + { SCALER_CROP_MAXIMUM, &ScalerCropMaximum }, + { SENSOR_SENSITIVITY, &SensorSensitivity }, + { SYSTEM_DEVICES, &SystemDevices }, + { PIPELINE_HANDLER, &PipelineHandler }, + { draft::COLOR_FILTER_ARRANGEMENT, &draft::ColorFilterArrangement }, +}; + +} /* namespace properties */ + +} /* namespace libcamera */ \ No newline at end of file diff --git a/meson_generated/src/libcamera/proxy/raspberrypi_ipa_proxy.cpp b/meson_generated/src/libcamera/proxy/raspberrypi_ipa_proxy.cpp new file mode 100644 index 00000000..1702280f --- /dev/null +++ b/meson_generated/src/libcamera/proxy/raspberrypi_ipa_proxy.cpp @@ -0,0 +1,683 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Google Inc. + * + * Image Processing Algorithm proxy for raspberrypi + * + * This file is auto-generated. Do not edit. + */ + +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "libcamera/internal/control_serializer.h" +#include "libcamera/internal/ipa_data_serializer.h" +#include "libcamera/internal/ipa_module.h" +#include "libcamera/internal/ipa_proxy.h" +#include "libcamera/internal/ipc_pipe.h" +#include "libcamera/internal/ipc_pipe_unixsocket.h" +#include "libcamera/internal/ipc_unixsocket.h" +#include "libcamera/internal/process.h" + +namespace libcamera { + +LOG_DECLARE_CATEGORY(IPAProxy) + +namespace ipa { + +namespace RPi { + + +IPAProxyRPiThreaded::IPAProxyRPiThreaded(IPAModule *ipam, const CameraManager &cm) + : IPAProxyRPi(ipam, cm), thread_("IPAProxyRPi") +{ + LOG(IPAProxy, Debug) + << "initializing raspberrypi proxy in thread: loading IPA from " + << ipam->path(); + + if (!ipam->load()) + return; + + IPAInterface *ipai = ipam->createInterface(); + if (!ipai) { + LOG(IPAProxy, Error) + << "Failed to create IPA context for " << ipam->path(); + return; + } + + ipa_ = std::unique_ptr(static_cast(ipai)); + proxy_.setIPA(ipa_.get()); + + + ipa_->prepareIspComplete.connect(this, &IPAProxyRPiThreaded::prepareIspCompleteHandler); + ipa_->processStatsComplete.connect(this, &IPAProxyRPiThreaded::processStatsCompleteHandler); + ipa_->metadataReady.connect(this, &IPAProxyRPiThreaded::metadataReadyHandler); + ipa_->setIspControls.connect(this, &IPAProxyRPiThreaded::setIspControlsHandler); + ipa_->setDelayedControls.connect(this, &IPAProxyRPiThreaded::setDelayedControlsHandler); + ipa_->setLensControls.connect(this, &IPAProxyRPiThreaded::setLensControlsHandler); + ipa_->setCameraTimeout.connect(this, &IPAProxyRPiThreaded::setCameraTimeoutHandler); + + valid_ = true; +} + +IPAProxyRPiThreaded::~IPAProxyRPiThreaded() = default; + + +int32_t IPAProxyRPiThreaded::init( + const IPASettings &settings, + const InitParams ¶ms, + InitResult *result) +{ + int32_t _ret = ipa_->init(settings, params, result); + + proxy_.moveToThread(&thread_); + + return _ret; +} + +void IPAProxyRPiThreaded::start( + const ControlList &controls, + StartResult *result) +{ + state_ = ProxyRunning; + thread_.start(); + + return proxy_.invokeMethod(&ThreadProxy::start, ConnectionTypeBlocking, controls, result); +} + +void IPAProxyRPiThreaded::stop() +{ + ASSERT(state_ != ProxyStopping); + if (state_ != ProxyRunning) + return; + + state_ = ProxyStopping; + + proxy_.invokeMethod(&ThreadProxy::stop, ConnectionTypeBlocking); + + thread_.exit(); + thread_.wait(); + + Thread::current()->dispatchMessages(Message::Type::InvokeMessage, this); + + state_ = ProxyStopped; +} + +int32_t IPAProxyRPiThreaded::configure( + const IPACameraSensorInfo &sensorInfo, + const ConfigParams ¶ms, + ConfigResult *result) +{ + return ipa_->configure(sensorInfo, params, result); + +} + +void IPAProxyRPiThreaded::mapBuffers( + const std::vector &buffers) +{ + return ipa_->mapBuffers(buffers); + +} + +void IPAProxyRPiThreaded::unmapBuffers( + const std::vector &ids) +{ + return ipa_->unmapBuffers(ids); + +} + +void IPAProxyRPiThreaded::prepareIsp( + const PrepareParams ¶ms) +{ + ASSERT(state_ == ProxyRunning); + proxy_.invokeMethod(&ThreadProxy::prepareIsp, ConnectionTypeQueued, params); +} + +void IPAProxyRPiThreaded::processStats( + const ProcessParams ¶ms) +{ + ASSERT(state_ == ProxyRunning); + proxy_.invokeMethod(&ThreadProxy::processStats, ConnectionTypeQueued, params); +} + + + +void IPAProxyRPiThreaded::prepareIspCompleteHandler( + const BufferIds &buffers, + const bool stitchSwapBuffers) +{ + ASSERT(state_ != ProxyStopped); + prepareIspComplete.emit(buffers, stitchSwapBuffers); +} + +void IPAProxyRPiThreaded::processStatsCompleteHandler( + const BufferIds &buffers) +{ + ASSERT(state_ != ProxyStopped); + processStatsComplete.emit(buffers); +} + +void IPAProxyRPiThreaded::metadataReadyHandler( + const ControlList &metadata) +{ + ASSERT(state_ != ProxyStopped); + metadataReady.emit(metadata); +} + +void IPAProxyRPiThreaded::setIspControlsHandler( + const ControlList &controls) +{ + ASSERT(state_ != ProxyStopped); + setIspControls.emit(controls); +} + +void IPAProxyRPiThreaded::setDelayedControlsHandler( + const ControlList &controls, + const uint32_t delayContext) +{ + ASSERT(state_ != ProxyStopped); + setDelayedControls.emit(controls, delayContext); +} + +void IPAProxyRPiThreaded::setLensControlsHandler( + const ControlList &controls) +{ + ASSERT(state_ != ProxyStopped); + setLensControls.emit(controls); +} + +void IPAProxyRPiThreaded::setCameraTimeoutHandler( + const uint32_t maxFrameLengthMs) +{ + ASSERT(state_ != ProxyStopped); + setCameraTimeout.emit(maxFrameLengthMs); +} + + +/* ========================================================================== */ + +IPAProxyRPiIsolated::IPAProxyRPiIsolated(IPAModule *ipam, const CameraManager &cm) + : IPAProxyRPi(ipam, cm), + controlSerializer_(ControlSerializer::Role::Proxy), seq_(0) +{ + LOG(IPAProxy, Debug) + << "initializing raspberrypi proxy in isolation: loading IPA from " + << ipam->path(); + + const std::string proxyWorkerPath = resolvePath("raspberrypi_ipa_proxy"); + if (proxyWorkerPath.empty()) { + LOG(IPAProxy, Error) << "Failed to get proxy worker path"; + return; + } + + auto ipc = std::make_unique(ipam->path().c_str(), + proxyWorkerPath.c_str()); + if (!ipc->isConnected()) { + LOG(IPAProxy, Error) << "Failed to create IPCPipe"; + return; + } + + ipc->recv.connect(this, &IPAProxyRPiIsolated::recvMessage); + + ipc_ = std::move(ipc); + valid_ = true; +} + +IPAProxyRPiIsolated::~IPAProxyRPiIsolated() +{ + if (ipc_) { + IPCMessage::Header header = + { static_cast(_RPiCmd::Exit), seq_++ }; + IPCMessage msg(header); + ipc_->sendAsync(msg); + } +} + + +int32_t IPAProxyRPiIsolated::init( + const IPASettings &settings, + const InitParams ¶ms, + InitResult *result) +{ + IPCMessage::Header _header = { static_cast(_RPiCmd::Init), seq_++ }; + IPCMessage _ipcInputBuf(_header); + IPCMessage _ipcOutputBuf; + + + std::vector settingsBuf; + std::tie(settingsBuf, std::ignore) = + IPADataSerializer::serialize(settings); + std::vector paramsBuf; + std::vector paramsFds; + std::tie(paramsBuf, paramsFds) = + IPADataSerializer::serialize(params); + appendPOD(_ipcInputBuf.data(), settingsBuf.size()); + appendPOD(_ipcInputBuf.data(), paramsBuf.size()); + appendPOD(_ipcInputBuf.data(), paramsFds.size()); + _ipcInputBuf.data().insert(_ipcInputBuf.data().end(), settingsBuf.begin(), settingsBuf.end()); + _ipcInputBuf.data().insert(_ipcInputBuf.data().end(), paramsBuf.begin(), paramsBuf.end()); + _ipcInputBuf.fds().insert(_ipcInputBuf.fds().end(), paramsFds.begin(), paramsFds.end()); + + + int _ret = ipc_->sendSync(_ipcInputBuf, &_ipcOutputBuf); + if (_ret < 0) { + LOG(IPAProxy, Error) << "Failed to call init: " << _ret; + return static_cast(_ret); + } + + int32_t _retValue = IPADataSerializer::deserialize(_ipcOutputBuf.data(), 0); + + + + const size_t resultStart = 4; + + + if (result) { + *result = + IPADataSerializer::deserialize( + _ipcOutputBuf.data().cbegin() + resultStart, + _ipcOutputBuf.data().cend(), + &controlSerializer_); + } + + + return _retValue; + +} + + +void IPAProxyRPiIsolated::start( + const ControlList &controls, + StartResult *result) +{ + IPCMessage::Header _header = { static_cast(_RPiCmd::Start), seq_++ }; + IPCMessage _ipcInputBuf(_header); + IPCMessage _ipcOutputBuf; + + + std::vector controlsBuf; + std::tie(controlsBuf, std::ignore) = + IPADataSerializer::serialize(controls, &controlSerializer_); + _ipcInputBuf.data().insert(_ipcInputBuf.data().end(), controlsBuf.begin(), controlsBuf.end()); + + + int _ret = ipc_->sendSync(_ipcInputBuf, &_ipcOutputBuf); + if (_ret < 0) { + LOG(IPAProxy, Error) << "Failed to call start: " << _ret; + return; + } + + + + const size_t resultStart = 0; + + + if (result) { + *result = + IPADataSerializer::deserialize( + _ipcOutputBuf.data().cbegin() + resultStart, + _ipcOutputBuf.data().cend(), + &controlSerializer_); + } + +} + + +void IPAProxyRPiIsolated::stop() +{ + IPCMessage::Header _header = { static_cast(_RPiCmd::Stop), seq_++ }; + IPCMessage _ipcInputBuf(_header); + + + + + int _ret = ipc_->sendSync(_ipcInputBuf); + if (_ret < 0) { + LOG(IPAProxy, Error) << "Failed to call stop: " << _ret; + return; + } +} + + +int32_t IPAProxyRPiIsolated::configure( + const IPACameraSensorInfo &sensorInfo, + const ConfigParams ¶ms, + ConfigResult *result) +{ + controlSerializer_.reset(); + IPCMessage::Header _header = { static_cast(_RPiCmd::Configure), seq_++ }; + IPCMessage _ipcInputBuf(_header); + IPCMessage _ipcOutputBuf; + + + std::vector sensorInfoBuf; + std::tie(sensorInfoBuf, std::ignore) = + IPADataSerializer::serialize(sensorInfo); + std::vector paramsBuf; + std::vector paramsFds; + std::tie(paramsBuf, paramsFds) = + IPADataSerializer::serialize(params, &controlSerializer_); + appendPOD(_ipcInputBuf.data(), sensorInfoBuf.size()); + appendPOD(_ipcInputBuf.data(), paramsBuf.size()); + appendPOD(_ipcInputBuf.data(), paramsFds.size()); + _ipcInputBuf.data().insert(_ipcInputBuf.data().end(), sensorInfoBuf.begin(), sensorInfoBuf.end()); + _ipcInputBuf.data().insert(_ipcInputBuf.data().end(), paramsBuf.begin(), paramsBuf.end()); + _ipcInputBuf.fds().insert(_ipcInputBuf.fds().end(), paramsFds.begin(), paramsFds.end()); + + + int _ret = ipc_->sendSync(_ipcInputBuf, &_ipcOutputBuf); + if (_ret < 0) { + LOG(IPAProxy, Error) << "Failed to call configure: " << _ret; + return static_cast(_ret); + } + + int32_t _retValue = IPADataSerializer::deserialize(_ipcOutputBuf.data(), 0); + + + + const size_t resultStart = 4; + + + if (result) { + *result = + IPADataSerializer::deserialize( + _ipcOutputBuf.data().cbegin() + resultStart, + _ipcOutputBuf.data().cend(), + &controlSerializer_); + } + + + return _retValue; + +} + + +void IPAProxyRPiIsolated::mapBuffers( + const std::vector &buffers) +{ + IPCMessage::Header _header = { static_cast(_RPiCmd::MapBuffers), seq_++ }; + IPCMessage _ipcInputBuf(_header); + + + std::vector buffersBuf; + std::vector buffersFds; + std::tie(buffersBuf, buffersFds) = + IPADataSerializer>::serialize(buffers); + _ipcInputBuf.data().insert(_ipcInputBuf.data().end(), buffersBuf.begin(), buffersBuf.end()); + _ipcInputBuf.fds().insert(_ipcInputBuf.fds().end(), buffersFds.begin(), buffersFds.end()); + + + int _ret = ipc_->sendSync(_ipcInputBuf); + if (_ret < 0) { + LOG(IPAProxy, Error) << "Failed to call mapBuffers: " << _ret; + return; + } +} + + +void IPAProxyRPiIsolated::unmapBuffers( + const std::vector &ids) +{ + IPCMessage::Header _header = { static_cast(_RPiCmd::UnmapBuffers), seq_++ }; + IPCMessage _ipcInputBuf(_header); + + + std::vector idsBuf; + std::tie(idsBuf, std::ignore) = + IPADataSerializer>::serialize(ids); + _ipcInputBuf.data().insert(_ipcInputBuf.data().end(), idsBuf.begin(), idsBuf.end()); + + + int _ret = ipc_->sendSync(_ipcInputBuf); + if (_ret < 0) { + LOG(IPAProxy, Error) << "Failed to call unmapBuffers: " << _ret; + return; + } +} + + +void IPAProxyRPiIsolated::prepareIsp( + const PrepareParams ¶ms) +{ + IPCMessage::Header _header = { static_cast(_RPiCmd::PrepareIsp), seq_++ }; + IPCMessage _ipcInputBuf(_header); + + + std::vector paramsBuf; + std::tie(paramsBuf, std::ignore) = + IPADataSerializer::serialize(params, &controlSerializer_); + _ipcInputBuf.data().insert(_ipcInputBuf.data().end(), paramsBuf.begin(), paramsBuf.end()); + + + int _ret = ipc_->sendAsync(_ipcInputBuf); + if (_ret < 0) { + LOG(IPAProxy, Error) << "Failed to call prepareIsp: " << _ret; + return; + } +} + + +void IPAProxyRPiIsolated::processStats( + const ProcessParams ¶ms) +{ + IPCMessage::Header _header = { static_cast(_RPiCmd::ProcessStats), seq_++ }; + IPCMessage _ipcInputBuf(_header); + + + std::vector paramsBuf; + std::tie(paramsBuf, std::ignore) = + IPADataSerializer::serialize(params); + _ipcInputBuf.data().insert(_ipcInputBuf.data().end(), paramsBuf.begin(), paramsBuf.end()); + + + int _ret = ipc_->sendAsync(_ipcInputBuf); + if (_ret < 0) { + LOG(IPAProxy, Error) << "Failed to call processStats: " << _ret; + return; + } +} + + + +void IPAProxyRPiIsolated::recvMessage(const IPCMessage &data) +{ + size_t dataSize = data.data().size(); + _RPiEventCmd _cmd = static_cast<_RPiEventCmd>(data.header().cmd); + + switch (_cmd) { + case _RPiEventCmd::PrepareIspComplete: { + prepareIspCompleteHandler(data.data().cbegin(), dataSize, data.fds()); + break; + } + case _RPiEventCmd::ProcessStatsComplete: { + processStatsCompleteHandler(data.data().cbegin(), dataSize, data.fds()); + break; + } + case _RPiEventCmd::MetadataReady: { + metadataReadyHandler(data.data().cbegin(), dataSize, data.fds()); + break; + } + case _RPiEventCmd::SetIspControls: { + setIspControlsHandler(data.data().cbegin(), dataSize, data.fds()); + break; + } + case _RPiEventCmd::SetDelayedControls: { + setDelayedControlsHandler(data.data().cbegin(), dataSize, data.fds()); + break; + } + case _RPiEventCmd::SetLensControls: { + setLensControlsHandler(data.data().cbegin(), dataSize, data.fds()); + break; + } + case _RPiEventCmd::SetCameraTimeout: { + setCameraTimeoutHandler(data.data().cbegin(), dataSize, data.fds()); + break; + } + default: + LOG(IPAProxy, Error) << "Unknown command " << static_cast(_cmd); + } +} + + +void IPAProxyRPiIsolated::prepareIspCompleteHandler( + [[maybe_unused]] std::vector::const_iterator data, + [[maybe_unused]] size_t dataSize, + [[maybe_unused]] const std::vector &fds) +{ + + [[maybe_unused]] const size_t buffersBufSize = readPOD(data, 0, data + dataSize); + [[maybe_unused]] const size_t stitchSwapBuffersBufSize = readPOD(data, 4, data + dataSize); + + const size_t buffersStart = 8; + const size_t stitchSwapBuffersStart = buffersStart + buffersBufSize; + + + BufferIds buffers = + IPADataSerializer::deserialize( + data + buffersStart, + data + buffersStart + buffersBufSize); + + bool stitchSwapBuffers = + IPADataSerializer::deserialize( + data + stitchSwapBuffersStart, + data + stitchSwapBuffersStart + stitchSwapBuffersBufSize); + + prepareIspComplete.emit(buffers, stitchSwapBuffers); +} + +void IPAProxyRPiIsolated::processStatsCompleteHandler( + [[maybe_unused]] std::vector::const_iterator data, + [[maybe_unused]] size_t dataSize, + [[maybe_unused]] const std::vector &fds) +{ + + + const size_t buffersStart = 0; + + + BufferIds buffers = + IPADataSerializer::deserialize( + data + buffersStart, + data + dataSize); + + processStatsComplete.emit(buffers); +} + +void IPAProxyRPiIsolated::metadataReadyHandler( + [[maybe_unused]] std::vector::const_iterator data, + [[maybe_unused]] size_t dataSize, + [[maybe_unused]] const std::vector &fds) +{ + + + const size_t metadataStart = 0; + + + ControlList metadata = + IPADataSerializer::deserialize( + data + metadataStart, + data + dataSize, + &controlSerializer_); + + metadataReady.emit(metadata); +} + +void IPAProxyRPiIsolated::setIspControlsHandler( + [[maybe_unused]] std::vector::const_iterator data, + [[maybe_unused]] size_t dataSize, + [[maybe_unused]] const std::vector &fds) +{ + + + const size_t controlsStart = 0; + + + ControlList controls = + IPADataSerializer::deserialize( + data + controlsStart, + data + dataSize, + &controlSerializer_); + + setIspControls.emit(controls); +} + +void IPAProxyRPiIsolated::setDelayedControlsHandler( + [[maybe_unused]] std::vector::const_iterator data, + [[maybe_unused]] size_t dataSize, + [[maybe_unused]] const std::vector &fds) +{ + + [[maybe_unused]] const size_t controlsBufSize = readPOD(data, 0, data + dataSize); + [[maybe_unused]] const size_t delayContextBufSize = readPOD(data, 4, data + dataSize); + + const size_t controlsStart = 8; + const size_t delayContextStart = controlsStart + controlsBufSize; + + + ControlList controls = + IPADataSerializer::deserialize( + data + controlsStart, + data + controlsStart + controlsBufSize, + &controlSerializer_); + + uint32_t delayContext = + IPADataSerializer::deserialize( + data + delayContextStart, + data + delayContextStart + delayContextBufSize); + + setDelayedControls.emit(controls, delayContext); +} + +void IPAProxyRPiIsolated::setLensControlsHandler( + [[maybe_unused]] std::vector::const_iterator data, + [[maybe_unused]] size_t dataSize, + [[maybe_unused]] const std::vector &fds) +{ + + + const size_t controlsStart = 0; + + + ControlList controls = + IPADataSerializer::deserialize( + data + controlsStart, + data + dataSize, + &controlSerializer_); + + setLensControls.emit(controls); +} + +void IPAProxyRPiIsolated::setCameraTimeoutHandler( + [[maybe_unused]] std::vector::const_iterator data, + [[maybe_unused]] size_t dataSize, + [[maybe_unused]] const std::vector &fds) +{ + + + const size_t maxFrameLengthMsStart = 0; + + + uint32_t maxFrameLengthMs = + IPADataSerializer::deserialize( + data + maxFrameLengthMsStart, + data + dataSize); + + setCameraTimeout.emit(maxFrameLengthMs); +} + + +} /* namespace RPi */ + +} /* namespace ipa */ + +} /* namespace libcamera */ \ No newline at end of file diff --git a/meson_generated/src/libcamera/version.cpp b/meson_generated/src/libcamera/version.cpp new file mode 100644 index 00000000..13284e6c --- /dev/null +++ b/meson_generated/src/libcamera/version.cpp @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * libcamera version + * + * This file is auto-generated. Do not edit. + */ + +#include + +namespace libcamera { + +const std::string CameraManager::version_("v0.7.1+6234-8bf59a6b"); + +} /* namespace libcamera */ diff --git a/meson_generated/utils/codegen/ipc/libcamera_templates.zip b/meson_generated/utils/codegen/ipc/libcamera_templates.zip new file mode 100644 index 0000000000000000000000000000000000000000..24dbfe084a8cab350e5b38227eadb0df3966ee93 GIT binary patch literal 131503 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 F{{t8Vumb=9 literal 0 HcmV?d00001