calibrate-pro 1.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- calibrate_pro-1.1.0/.github/FUNDING.yml +2 -0
- calibrate_pro-1.1.0/.github/workflows/ci.yml +56 -0
- calibrate_pro-1.1.0/.github/workflows/release.yml +203 -0
- calibrate_pro-1.1.0/ARCHITECTURE.md +111 -0
- calibrate_pro-1.1.0/AUTHORS.md +12 -0
- calibrate_pro-1.1.0/CHANGELOG.md +50 -0
- calibrate_pro-1.1.0/CONTRIBUTING.md +10 -0
- calibrate_pro-1.1.0/LICENSE +110 -0
- calibrate_pro-1.1.0/MANIFEST.in +31 -0
- calibrate_pro-1.1.0/PKG-INFO +245 -0
- calibrate_pro-1.1.0/README.md +193 -0
- calibrate_pro-1.1.0/RELEASE_NOTES.md +42 -0
- calibrate_pro-1.1.0/SECURITY.md +140 -0
- calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/Build-Color-1.0.2.txt +110 -0
- calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/Build-UI-2.0.0.txt +110 -0
- calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/CPython-3.12.10-Windows-Externals-NOTICE.txt +732 -0
- calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/LGPL-3.0-only.txt +165 -0
- calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/LGPL_RELINKING.md +11 -0
- calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/Microsoft-Visual-Cpp-Runtime-NOTICE.txt +65 -0
- calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/NumPy-2.5.1.txt +914 -0
- calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/OpenBLAS.txt +29 -0
- calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/Packaging-26.2.txt +216 -0
- calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/PyInstaller-6.21.0.txt +636 -0
- calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/Python-3.12.10.txt +279 -0
- calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/QT_SOURCE_OFFER.txt +125 -0
- calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/Qt-6.11.1-THIRD-PARTY-NOTICES.txt +881 -0
- calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/Qt-for-Python-NOTICE.txt +21 -0
- calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/QtPy-2.4.3.txt +21 -0
- calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/README.md +32 -0
- calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/SciPy-1.18.0.txt +915 -0
- calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/hidapi-0.15.0.txt +728 -0
- calibrate_pro-1.1.0/USAGE.md +169 -0
- calibrate_pro-1.1.0/calibrate-pro.spec +268 -0
- calibrate_pro-1.1.0/calibrate_pro/__init__.py +59 -0
- calibrate_pro-1.1.0/calibrate_pro/__main__.py +5 -0
- calibrate_pro-1.1.0/calibrate_pro/actuation.py +212 -0
- calibrate_pro-1.1.0/calibrate_pro/adapters/__init__.py +21 -0
- calibrate_pro-1.1.0/calibrate_pro/adapters/windows_display_state.py +4826 -0
- calibrate_pro-1.1.0/calibrate_pro/advanced/__init__.py +272 -0
- calibrate_pro-1.1.0/calibrate_pro/advanced/ambient_light.py +913 -0
- calibrate_pro-1.1.0/calibrate_pro/advanced/automation.py +1057 -0
- calibrate_pro-1.1.0/calibrate_pro/advanced/demo.py +359 -0
- calibrate_pro-1.1.0/calibrate_pro/advanced/lut_optimization.py +839 -0
- calibrate_pro-1.1.0/calibrate_pro/advanced/network_calibration.py +939 -0
- calibrate_pro-1.1.0/calibrate_pro/advanced/uniformity.py +817 -0
- calibrate_pro-1.1.0/calibrate_pro/app.py +25 -0
- calibrate_pro-1.1.0/calibrate_pro/calibration/__init__.py +14 -0
- calibrate_pro-1.1.0/calibrate_pro/calibration/ccss_import.py +361 -0
- calibrate_pro-1.1.0/calibrate_pro/calibration/hardware_first.py +367 -0
- calibrate_pro-1.1.0/calibrate_pro/calibration/hybrid.py +390 -0
- calibrate_pro-1.1.0/calibrate_pro/calibration/multi_display.py +189 -0
- calibrate_pro-1.1.0/calibrate_pro/calibration/native_loop.py +413 -0
- calibrate_pro-1.1.0/calibrate_pro/calibration/targets.py +409 -0
- calibrate_pro-1.1.0/calibrate_pro/commands/__init__.py +1 -0
- calibrate_pro-1.1.0/calibrate_pro/commands/doctor.py +14 -0
- calibrate_pro-1.1.0/calibrate_pro/commands/gui.py +26 -0
- calibrate_pro-1.1.0/calibrate_pro/commands/hdr.py +26 -0
- calibrate_pro-1.1.0/calibrate_pro/community/__init__.py +6 -0
- calibrate_pro-1.1.0/calibrate_pro/community/database.py +377 -0
- calibrate_pro-1.1.0/calibrate_pro/core/__init__.py +199 -0
- calibrate_pro-1.1.0/calibrate_pro/core/aces.py +876 -0
- calibrate_pro-1.1.0/calibrate_pro/core/calibration_engine.py +915 -0
- calibrate_pro-1.1.0/calibrate_pro/core/color_math.py +1709 -0
- calibrate_pro-1.1.0/calibrate_pro/core/color_models.py +925 -0
- calibrate_pro-1.1.0/calibrate_pro/core/icc_profile.py +592 -0
- calibrate_pro-1.1.0/calibrate_pro/core/lut_engine.py +1468 -0
- calibrate_pro-1.1.0/calibrate_pro/core/lut_engine_advanced.py +850 -0
- calibrate_pro-1.1.0/calibrate_pro/core/pq.py +43 -0
- calibrate_pro-1.1.0/calibrate_pro/core/vcgt.py +593 -0
- calibrate_pro-1.1.0/calibrate_pro/diagnostics.py +259 -0
- calibrate_pro-1.1.0/calibrate_pro/display/__init__.py +20 -0
- calibrate_pro-1.1.0/calibrate_pro/display/color_volume.py +231 -0
- calibrate_pro-1.1.0/calibrate_pro/display/hdr_content.py +342 -0
- calibrate_pro-1.1.0/calibrate_pro/display/hdr_detect.py +246 -0
- calibrate_pro-1.1.0/calibrate_pro/display/oled.py +303 -0
- calibrate_pro-1.1.0/calibrate_pro/display/scrgb_pipeline.py +418 -0
- calibrate_pro-1.1.0/calibrate_pro/display/uniformity.py +429 -0
- calibrate_pro-1.1.0/calibrate_pro/frozen_main.py +89 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/__init__.py +140 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/app.py +2110 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/calibration_details.py +415 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/calibration_test.py +914 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/calibration_wizard.py +1285 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/dialogs.py +522 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/display_selector.py +659 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/hdr_calibration.py +528 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/icons.py +226 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/lut_preview.py +783 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/main_window.py +481 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/measurement_view.py +572 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/pages/__init__.py +0 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/pages/calibrate.py +1043 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/pages/calibration_page.py +568 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/pages/color_control_page.py +504 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/pages/dashboard_page.py +554 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/pages/ddc_control.py +593 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/pages/ddc_control_page.py +1115 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/pages/profiles.py +582 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/pages/profiles_page.py +734 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/pages/settings.py +568 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/pages/settings_page.py +229 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/pages/vcgt_tools_page.py +274 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/pages/verification_page.py +335 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/pages/verify.py +1273 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/pattern_window.py +763 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/professional_calibration.py +1079 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/profile_manager.py +367 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/report_viewer.py +591 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/theme.py +92 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/widgets/__init__.py +99 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/widgets/cie_diagram.py +826 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/widgets/color_swatch.py +449 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/widgets/delta_e_chart.py +462 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/widgets/gamma_curve.py +482 -0
- calibrate_pro-1.1.0/calibrate_pro/gui/workers.py +103 -0
- calibrate_pro-1.1.0/calibrate_pro/hardware/__init__.py +443 -0
- calibrate_pro-1.1.0/calibrate_pro/hardware/argyll_backend.py +699 -0
- calibrate_pro-1.1.0/calibrate_pro/hardware/colorimeter_base.py +503 -0
- calibrate_pro-1.1.0/calibrate_pro/hardware/ddc_ci.py +1632 -0
- calibrate_pro-1.1.0/calibrate_pro/hardware/drift_compensation.py +174 -0
- calibrate_pro-1.1.0/calibrate_pro/hardware/hardware_calibration.py +869 -0
- calibrate_pro-1.1.0/calibrate_pro/hardware/i1d3_native.py +565 -0
- calibrate_pro-1.1.0/calibrate_pro/hardware/i1display.py +351 -0
- calibrate_pro-1.1.0/calibrate_pro/hardware/i1display_native.py +485 -0
- calibrate_pro-1.1.0/calibrate_pro/hardware/measurement.py +262 -0
- calibrate_pro-1.1.0/calibrate_pro/hardware/native_backend.py +268 -0
- calibrate_pro-1.1.0/calibrate_pro/hardware/sensorless_calibration.py +1928 -0
- calibrate_pro-1.1.0/calibrate_pro/hardware/spectro.py +394 -0
- calibrate_pro-1.1.0/calibrate_pro/hardware/spyder.py +392 -0
- calibrate_pro-1.1.0/calibrate_pro/hardware/spyder_native.py +490 -0
- calibrate_pro-1.1.0/calibrate_pro/hardware/usb_device.py +379 -0
- calibrate_pro-1.1.0/calibrate_pro/hardware/warmup_monitor.py +192 -0
- calibrate_pro-1.1.0/calibrate_pro/hdr/__init__.py +446 -0
- calibrate_pro-1.1.0/calibrate_pro/hdr/dolby_vision.py +622 -0
- calibrate_pro-1.1.0/calibrate_pro/hdr/eotf_calibration.py +654 -0
- calibrate_pro-1.1.0/calibrate_pro/hdr/hdr10plus.py +613 -0
- calibrate_pro-1.1.0/calibrate_pro/hdr/hdr_calibration.py +631 -0
- calibrate_pro-1.1.0/calibrate_pro/hdr/hlg.py +339 -0
- calibrate_pro-1.1.0/calibrate_pro/hdr/mastering_standards.py +511 -0
- calibrate_pro-1.1.0/calibrate_pro/hdr/pq_st2084.py +349 -0
- calibrate_pro-1.1.0/calibrate_pro/hdr/tone_mapping.py +541 -0
- calibrate_pro-1.1.0/calibrate_pro/hdr/workflow.py +400 -0
- calibrate_pro-1.1.0/calibrate_pro/integrations/__init__.py +1 -0
- calibrate_pro-1.1.0/calibrate_pro/integrations/resolve.py +133 -0
- calibrate_pro-1.1.0/calibrate_pro/lut_system/__init__.py +589 -0
- calibrate_pro-1.1.0/calibrate_pro/lut_system/amd_api.py +1374 -0
- calibrate_pro-1.1.0/calibrate_pro/lut_system/color_loader.py +726 -0
- calibrate_pro-1.1.0/calibrate_pro/lut_system/dwm_lut.py +1186 -0
- calibrate_pro-1.1.0/calibrate_pro/lut_system/intel_api.py +350 -0
- calibrate_pro-1.1.0/calibrate_pro/lut_system/lut_formats.py +890 -0
- calibrate_pro-1.1.0/calibrate_pro/lut_system/nvidia_api.py +1138 -0
- calibrate_pro-1.1.0/calibrate_pro/lut_system/per_display_calibration.py +556 -0
- calibrate_pro-1.1.0/calibrate_pro/lut_system/vcgt_calibration.py +459 -0
- calibrate_pro-1.1.0/calibrate_pro/main.py +305 -0
- calibrate_pro-1.1.0/calibrate_pro/panels/__init__.py +1 -0
- calibrate_pro-1.1.0/calibrate_pro/panels/builtin_panels.py +2735 -0
- calibrate_pro-1.1.0/calibrate_pro/panels/database.py +247 -0
- calibrate_pro-1.1.0/calibrate_pro/panels/detection.py +2288 -0
- calibrate_pro-1.1.0/calibrate_pro/panels/panel_types.py +167 -0
- calibrate_pro-1.1.0/calibrate_pro/patterns/__init__.py +10 -0
- calibrate_pro-1.1.0/calibrate_pro/patterns/display.py +369 -0
- calibrate_pro-1.1.0/calibrate_pro/platform/__init__.py +60 -0
- calibrate_pro-1.1.0/calibrate_pro/platform/base.py +145 -0
- calibrate_pro-1.1.0/calibrate_pro/platform/linux.py +751 -0
- calibrate_pro-1.1.0/calibrate_pro/platform/macos.py +415 -0
- calibrate_pro-1.1.0/calibrate_pro/platform/windows.py +174 -0
- calibrate_pro-1.1.0/calibrate_pro/plugins/__init__.py +18 -0
- calibrate_pro-1.1.0/calibrate_pro/plugins/manager.py +380 -0
- calibrate_pro-1.1.0/calibrate_pro/profiles/__init__.py +242 -0
- calibrate_pro-1.1.0/calibrate_pro/profiles/icc_v4.py +870 -0
- calibrate_pro-1.1.0/calibrate_pro/profiles/mhc2.py +1110 -0
- calibrate_pro-1.1.0/calibrate_pro/profiles/profile_installer.py +2825 -0
- calibrate_pro-1.1.0/calibrate_pro/profiles/vcgt.py +762 -0
- calibrate_pro-1.1.0/calibrate_pro/qt_runtime.py +22 -0
- calibrate_pro-1.1.0/calibrate_pro/recovery.py +394 -0
- calibrate_pro-1.1.0/calibrate_pro/resources/calibrate_pro.ico +0 -0
- calibrate_pro-1.1.0/calibrate_pro/resources/calibrate_pro.png +0 -0
- calibrate_pro-1.1.0/calibrate_pro/runtime.py +18 -0
- calibrate_pro-1.1.0/calibrate_pro/sensorless/__init__.py +117 -0
- calibrate_pro-1.1.0/calibrate_pro/sensorless/auto_calibration.py +1863 -0
- calibrate_pro-1.1.0/calibrate_pro/sensorless/camera_calibration.py +682 -0
- calibrate_pro-1.1.0/calibrate_pro/sensorless/neuralux.py +965 -0
- calibrate_pro-1.1.0/calibrate_pro/sensorless/pattern_generator.py +356 -0
- calibrate_pro-1.1.0/calibrate_pro/sensorless/visual_matcher.py +427 -0
- calibrate_pro-1.1.0/calibrate_pro/services/__init__.py +18 -0
- calibrate_pro-1.1.0/calibrate_pro/services/ambient_light.py +417 -0
- calibrate_pro-1.1.0/calibrate_pro/services/app_switcher.py +425 -0
- calibrate_pro-1.1.0/calibrate_pro/services/calibration_guard.py +244 -0
- calibrate_pro-1.1.0/calibrate_pro/services/drift_monitor.py +183 -0
- calibrate_pro-1.1.0/calibrate_pro/services/gamut_clamp.py +117 -0
- calibrate_pro-1.1.0/calibrate_pro/startup/__init__.py +27 -0
- calibrate_pro-1.1.0/calibrate_pro/startup/calibration_loader.py +161 -0
- calibrate_pro-1.1.0/calibrate_pro/startup/lut_autoload.py +99 -0
- calibrate_pro-1.1.0/calibrate_pro/targets/__init__.py +359 -0
- calibrate_pro-1.1.0/calibrate_pro/targets/gamma.py +632 -0
- calibrate_pro-1.1.0/calibrate_pro/targets/gamut.py +613 -0
- calibrate_pro-1.1.0/calibrate_pro/targets/luminance.py +618 -0
- calibrate_pro-1.1.0/calibrate_pro/targets/whitepoint.py +475 -0
- calibrate_pro-1.1.0/calibrate_pro/tray/__init__.py +10 -0
- calibrate_pro-1.1.0/calibrate_pro/tray/tray_app.py +281 -0
- calibrate_pro-1.1.0/calibrate_pro/utils/__init__.py +1 -0
- calibrate_pro-1.1.0/calibrate_pro/utils/auto_calibration.py +530 -0
- calibrate_pro-1.1.0/calibrate_pro/utils/startup_manager.py +257 -0
- calibrate_pro-1.1.0/calibrate_pro/verification/__init__.py +318 -0
- calibrate_pro-1.1.0/calibrate_pro/verification/colorchecker.py +716 -0
- calibrate_pro-1.1.0/calibrate_pro/verification/gamut_volume.py +958 -0
- calibrate_pro-1.1.0/calibrate_pro/verification/grayscale.py +887 -0
- calibrate_pro-1.1.0/calibrate_pro/verification/measured_verify.py +640 -0
- calibrate_pro-1.1.0/calibrate_pro/verification/patch_sets.py +707 -0
- calibrate_pro-1.1.0/calibrate_pro/verification/pdf_export.py +110 -0
- calibrate_pro-1.1.0/calibrate_pro/verification/provenance.py +49 -0
- calibrate_pro-1.1.0/calibrate_pro/verification/report_generator.py +1436 -0
- calibrate_pro-1.1.0/calibrate_pro/verification/reports.py +1228 -0
- calibrate_pro-1.1.0/calibrate_pro/workflow.py +250 -0
- calibrate_pro-1.1.0/calibrate_pro.egg-info/PKG-INFO +245 -0
- calibrate_pro-1.1.0/calibrate_pro.egg-info/SOURCES.txt +311 -0
- calibrate_pro-1.1.0/calibrate_pro.egg-info/dependency_links.txt +1 -0
- calibrate_pro-1.1.0/calibrate_pro.egg-info/entry_points.txt +2 -0
- calibrate_pro-1.1.0/calibrate_pro.egg-info/requires.txt +42 -0
- calibrate_pro-1.1.0/calibrate_pro.egg-info/top_level.txt +1 -0
- calibrate_pro-1.1.0/docs/ENTERPRISE-READINESS.md +84 -0
- calibrate_pro-1.1.0/docs/INDUSTRY_FEATURES.md +98 -0
- calibrate_pro-1.1.0/docs/TECHNICAL.md +147 -0
- calibrate_pro-1.1.0/docs/UI_ROADMAP.md +240 -0
- calibrate_pro-1.1.0/docs/brand/README.md +15 -0
- calibrate_pro-1.1.0/docs/brand/calibrate-pro-hero.png +0 -0
- calibrate_pro-1.1.0/docs/brand/calibrate-pro-hero.svg +18 -0
- calibrate_pro-1.1.0/docs/brand/calibrate-pro-mark.svg +8 -0
- calibrate_pro-1.1.0/docs/index.html +179 -0
- calibrate_pro-1.1.0/docs/superpowers/plans/2026-07-10-calibrate-pro-1.1-pyside-packaging.md +2495 -0
- calibrate_pro-1.1.0/docs/superpowers/specs/2026-07-09-calibrate-pro-packaging-polish-design.md +531 -0
- calibrate_pro-1.1.0/docs/superpowers/specs/2026-07-10-cp-hdr-1-measured-display-characterization-design.md +452 -0
- calibrate_pro-1.1.0/dwm_lut/DwmLutGUI.exe +0 -0
- calibrate_pro-1.1.0/dwm_lut/LICENSE +674 -0
- calibrate_pro-1.1.0/dwm_lut/LICENSE-THIRD-PARTY +493 -0
- calibrate_pro-1.1.0/dwm_lut/WindowsDisplayAPI.dll +0 -0
- calibrate_pro-1.1.0/dwm_lut/dwm_lut.dll +0 -0
- calibrate_pro-1.1.0/examples/inspect_panels.py +59 -0
- calibrate_pro-1.1.0/installer/CalibratePro.iss +43 -0
- calibrate_pro-1.1.0/packaging/binary-provenance.lock.json +142 -0
- calibrate_pro-1.1.0/packaging/components-win64.json +1030 -0
- calibrate_pro-1.1.0/packaging/frozen-features.json +34 -0
- calibrate_pro-1.1.0/packaging/frozen-modules.json +135 -0
- calibrate_pro-1.1.0/packaging/pyi_rth_qt_api.py +6 -0
- calibrate_pro-1.1.0/packaging/qt-components.json +70 -0
- calibrate_pro-1.1.0/packaging/requirements-win64-py312.lock +480 -0
- calibrate_pro-1.1.0/packaging/requirements-win64.in +13 -0
- calibrate_pro-1.1.0/packaging/source-provenance.lock.json +222 -0
- calibrate_pro-1.1.0/packaging/toolchain-win64.json +15 -0
- calibrate_pro-1.1.0/pyproject.toml +122 -0
- calibrate_pro-1.1.0/scripts/build_windows.ps1 +325 -0
- calibrate_pro-1.1.0/scripts/ccmx_calibration_loop.py +441 -0
- calibrate_pro-1.1.0/scripts/ccmx_chroma_adaptive.py +374 -0
- calibrate_pro-1.1.0/scripts/ccmx_verification.py +313 -0
- calibrate_pro-1.1.0/scripts/hybrid_measure.py +282 -0
- calibrate_pro-1.1.0/scripts/native_calibration_loop.py +629 -0
- calibrate_pro-1.1.0/scripts/native_calibration_loop_v2.py +641 -0
- calibrate_pro-1.1.0/scripts/native_colorchecker.py +243 -0
- calibrate_pro-1.1.0/scripts/native_iterative_refine.py +385 -0
- calibrate_pro-1.1.0/scripts/normalize_sdist.py +117 -0
- calibrate_pro-1.1.0/scripts/release_artifacts.py +891 -0
- calibrate_pro-1.1.0/scripts/smoke_frozen.ps1 +51 -0
- calibrate_pro-1.1.0/scripts/unlock_measure.py +136 -0
- calibrate_pro-1.1.0/scripts/vcgt_measure.py +221 -0
- calibrate_pro-1.1.0/scripts/verify_binary_provenance.py +173 -0
- calibrate_pro-1.1.0/scripts/verify_pe_manifest.py +90 -0
- calibrate_pro-1.1.0/scripts/verify_release_asset_set.py +97 -0
- calibrate_pro-1.1.0/scripts/verify_reproducibility.ps1 +70 -0
- calibrate_pro-1.1.0/scripts/verify_source_provenance.py +211 -0
- calibrate_pro-1.1.0/setup.cfg +4 -0
- calibrate_pro-1.1.0/tests/__init__.py +0 -0
- calibrate_pro-1.1.0/tests/conftest.py +70 -0
- calibrate_pro-1.1.0/tests/data/gui-public-api-1.0.json +19 -0
- calibrate_pro-1.1.0/tests/data/st2084-gold-vectors.json +15 -0
- calibrate_pro-1.1.0/tests/test_actuator_boundary.py +447 -0
- calibrate_pro-1.1.0/tests/test_auto_calibration.py +310 -0
- calibrate_pro-1.1.0/tests/test_binary_provenance.py +85 -0
- calibrate_pro-1.1.0/tests/test_color_math.py +458 -0
- calibrate_pro-1.1.0/tests/test_ddc_ci_safety.py +471 -0
- calibrate_pro-1.1.0/tests/test_diagnostics.py +316 -0
- calibrate_pro-1.1.0/tests/test_frozen_module_allowlist.py +169 -0
- calibrate_pro-1.1.0/tests/test_gui_lazy_imports.py +83 -0
- calibrate_pro-1.1.0/tests/test_gui_truthfulness.py +118 -0
- calibrate_pro-1.1.0/tests/test_hdr_provenance.py +193 -0
- calibrate_pro-1.1.0/tests/test_hdr_workflow.py +446 -0
- calibrate_pro-1.1.0/tests/test_least_privilege.py +218 -0
- calibrate_pro-1.1.0/tests/test_lut_engine.py +239 -0
- calibrate_pro-1.1.0/tests/test_native_loop.py +159 -0
- calibrate_pro-1.1.0/tests/test_packaging_contract.py +200 -0
- calibrate_pro-1.1.0/tests/test_panel_database.py +204 -0
- calibrate_pro-1.1.0/tests/test_pdf_export.py +94 -0
- calibrate_pro-1.1.0/tests/test_platform.py +711 -0
- calibrate_pro-1.1.0/tests/test_pq_conformance.py +217 -0
- calibrate_pro-1.1.0/tests/test_professional_features.py +222 -0
- calibrate_pro-1.1.0/tests/test_profile_installer_portability.py +32 -0
- calibrate_pro-1.1.0/tests/test_profile_installer_safety.py +3293 -0
- calibrate_pro-1.1.0/tests/test_public_release_docs.py +149 -0
- calibrate_pro-1.1.0/tests/test_pypi_release_workflow.py +169 -0
- calibrate_pro-1.1.0/tests/test_python_compatibility.py +46 -0
- calibrate_pro-1.1.0/tests/test_qt_binding_contract.py +139 -0
- calibrate_pro-1.1.0/tests/test_qt_redistribution.py +301 -0
- calibrate_pro-1.1.0/tests/test_release_artifacts.py +641 -0
- calibrate_pro-1.1.0/tests/test_release_asset_set.py +50 -0
- calibrate_pro-1.1.0/tests/test_release_lock.py +88 -0
- calibrate_pro-1.1.0/tests/test_release_metadata.py +91 -0
- calibrate_pro-1.1.0/tests/test_release_pipeline_contract.py +119 -0
- calibrate_pro-1.1.0/tests/test_report_truthfulness.py +136 -0
- calibrate_pro-1.1.0/tests/test_sdist_reproducibility.py +74 -0
- calibrate_pro-1.1.0/tests/test_truthfulness_contract.py +137 -0
- calibrate_pro-1.1.0/tests/test_verification.py +139 -0
- calibrate_pro-1.1.0/tests/test_windows_ctypes_abi.py +1343 -0
- calibrate_pro-1.1.0/tests/test_windows_display_state_adapter.py +9430 -0
- calibrate_pro-1.1.0/tests/test_workflow.py +1076 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
lint:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
|
14
|
+
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
|
|
15
|
+
with:
|
|
16
|
+
python-version: "3.12"
|
|
17
|
+
- name: Install pinned ruff + mypy
|
|
18
|
+
run: pip install ruff==0.15.21 mypy==2.2.0
|
|
19
|
+
- name: Lint
|
|
20
|
+
run: ruff check .
|
|
21
|
+
- name: Format check
|
|
22
|
+
run: ruff format --check .
|
|
23
|
+
- name: Type check (mypy)
|
|
24
|
+
run: mypy --platform win32
|
|
25
|
+
|
|
26
|
+
test:
|
|
27
|
+
runs-on: ${{ matrix.os }}
|
|
28
|
+
env:
|
|
29
|
+
QT_API: pyside6
|
|
30
|
+
QT_QPA_PLATFORM: offscreen
|
|
31
|
+
strategy:
|
|
32
|
+
matrix:
|
|
33
|
+
os: [ubuntu-latest, windows-latest]
|
|
34
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
35
|
+
steps:
|
|
36
|
+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
|
37
|
+
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
|
|
38
|
+
with:
|
|
39
|
+
python-version: ${{ matrix.python-version }}
|
|
40
|
+
- name: Install Linux Qt runtime libraries
|
|
41
|
+
if: runner.os == 'Linux'
|
|
42
|
+
run: |
|
|
43
|
+
sudo apt-get update
|
|
44
|
+
sudo apt-get install -y libegl1 libxkbcommon0
|
|
45
|
+
- name: Install dependencies
|
|
46
|
+
run: |
|
|
47
|
+
python -m pip install --upgrade pip
|
|
48
|
+
python -m pip install -e ".[all,test]"
|
|
49
|
+
- name: Run portable tests with coverage
|
|
50
|
+
if: runner.os == 'Linux'
|
|
51
|
+
run: pytest tests/ -q -m "not windows" --cov=calibrate_pro --cov-report=term-missing --cov-fail-under=15
|
|
52
|
+
- name: Run complete Windows tests with coverage
|
|
53
|
+
if: runner.os == 'Windows'
|
|
54
|
+
env:
|
|
55
|
+
COVERAGE_CORE: ${{ matrix.python-version == '3.12' && 'sysmon' || 'ctrace' }}
|
|
56
|
+
run: pytest tests/ -q --cov=calibrate_pro --cov-report=term-missing --cov-fail-under=15
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
inputs:
|
|
6
|
+
publish:
|
|
7
|
+
description: Publish the already accepted release assets to PyPI
|
|
8
|
+
required: true
|
|
9
|
+
type: boolean
|
|
10
|
+
default: false
|
|
11
|
+
release_tag:
|
|
12
|
+
description: Existing GitHub release tag whose assets were accepted
|
|
13
|
+
required: true
|
|
14
|
+
type: string
|
|
15
|
+
default: v1.1.0
|
|
16
|
+
release:
|
|
17
|
+
types: [published]
|
|
18
|
+
|
|
19
|
+
permissions:
|
|
20
|
+
contents: read
|
|
21
|
+
|
|
22
|
+
env:
|
|
23
|
+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
|
24
|
+
|
|
25
|
+
jobs:
|
|
26
|
+
candidate:
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
env:
|
|
29
|
+
QT_API: pyside6
|
|
30
|
+
QT_QPA_PLATFORM: offscreen
|
|
31
|
+
steps:
|
|
32
|
+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
|
33
|
+
with:
|
|
34
|
+
ref: ${{ github.event_name == 'release' && github.event.release.tag_name || inputs.release_tag }}
|
|
35
|
+
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
|
|
36
|
+
with:
|
|
37
|
+
python-version: "3.12"
|
|
38
|
+
- name: Install Linux Qt runtime libraries
|
|
39
|
+
run: |
|
|
40
|
+
sudo apt-get update
|
|
41
|
+
sudo apt-get install -y libegl1 libxkbcommon0
|
|
42
|
+
- name: Install candidate and verification tools
|
|
43
|
+
run: |
|
|
44
|
+
python -m pip install --upgrade build pytest pytest-cov twine
|
|
45
|
+
python -m pip install ".[all,test]"
|
|
46
|
+
- name: Verify source candidate
|
|
47
|
+
run: python -m pytest -q -m "not windows"
|
|
48
|
+
- name: Verify corresponding-source archives
|
|
49
|
+
run: python scripts/verify_source_provenance.py packaging/source-provenance.lock.json
|
|
50
|
+
- name: Build distributions
|
|
51
|
+
run: python -m build
|
|
52
|
+
- name: Check distributions
|
|
53
|
+
run: python -m twine check dist/*
|
|
54
|
+
|
|
55
|
+
windows-candidate:
|
|
56
|
+
runs-on: windows-2022
|
|
57
|
+
env:
|
|
58
|
+
QT_API: pyside6
|
|
59
|
+
QT_QPA_PLATFORM: offscreen
|
|
60
|
+
steps:
|
|
61
|
+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
|
62
|
+
with:
|
|
63
|
+
ref: ${{ github.event_name == 'release' && github.event.release.tag_name || inputs.release_tag }}
|
|
64
|
+
- name: Install the hash-locked official CPython release runtime
|
|
65
|
+
shell: pwsh
|
|
66
|
+
run: |
|
|
67
|
+
$binaryLock = Get-Content -Raw -LiteralPath 'packaging/binary-provenance.lock.json' | ConvertFrom-Json
|
|
68
|
+
$pythonEntries = @(
|
|
69
|
+
$binaryLock.components | Where-Object { $_.name -eq 'cpython-3.12.10-amd64-installer' }
|
|
70
|
+
)
|
|
71
|
+
if ($pythonEntries.Count -ne 1) { throw "Expected exactly one locked CPython installer; found $($pythonEntries.Count)" }
|
|
72
|
+
$pythonEntry = $pythonEntries[0]
|
|
73
|
+
if ($pythonEntry.version -ne '3.12.10' -or $pythonEntry.artifact_type -ne 'exe') {
|
|
74
|
+
throw 'The locked CPython release runtime does not match the approved toolchain'
|
|
75
|
+
}
|
|
76
|
+
$pythonUri = [Uri]$pythonEntry.artifact_url
|
|
77
|
+
if ($pythonUri.Scheme -ne 'https' -or @($pythonEntry.allowed_final_hosts) -notcontains $pythonUri.Host) {
|
|
78
|
+
throw "The locked CPython installer URL is not an approved HTTPS origin: $pythonUri"
|
|
79
|
+
}
|
|
80
|
+
$pythonInstaller = Join-Path $env:RUNNER_TEMP ([string]$pythonEntry.filename)
|
|
81
|
+
$pythonRoot = Join-Path $env:RUNNER_TEMP 'python-3.12.10-official'
|
|
82
|
+
Invoke-WebRequest -Uri $pythonEntry.artifact_url -MaximumRedirection 0 -OutFile $pythonInstaller
|
|
83
|
+
$actualHash = (Get-FileHash -LiteralPath $pythonInstaller -Algorithm SHA256).Hash.ToLowerInvariant()
|
|
84
|
+
if ($actualHash -ne [string]$pythonEntry.sha256) { throw "Unexpected CPython installer hash: $actualHash" }
|
|
85
|
+
$signature = Get-AuthenticodeSignature -LiteralPath $pythonInstaller
|
|
86
|
+
if ($signature.Status -ne 'Valid' -or $signature.SignerCertificate.Subject -notmatch 'Python Software Foundation') {
|
|
87
|
+
throw "CPython installer signature is not valid for the Python Software Foundation: $($signature.Status)"
|
|
88
|
+
}
|
|
89
|
+
$pythonInstall = Start-Process -FilePath $pythonInstaller `
|
|
90
|
+
-ArgumentList @(
|
|
91
|
+
'/quiet', 'InstallAllUsers=0', "TargetDir=$pythonRoot", 'Include_launcher=0',
|
|
92
|
+
'InstallLauncherAllUsers=0', 'Include_test=0', 'Include_doc=0', 'Shortcuts=0',
|
|
93
|
+
'AssociateFiles=0', 'PrependPath=0', 'AppendPath=0'
|
|
94
|
+
) -Wait -PassThru -WindowStyle Hidden
|
|
95
|
+
if ($pythonInstall.ExitCode -ne 0) { throw "CPython installation failed: $($pythonInstall.ExitCode)" }
|
|
96
|
+
$python = Join-Path $pythonRoot 'python.exe'
|
|
97
|
+
if (-not (Test-Path -LiteralPath $python -PathType Leaf)) { throw 'The official CPython runtime was not installed' }
|
|
98
|
+
$actualVersion = (& $python -c 'import platform; print(platform.python_version())').Trim()
|
|
99
|
+
if ($actualVersion -ne [string]$pythonEntry.version) { throw "Unexpected CPython runtime version: $actualVersion" }
|
|
100
|
+
foreach ($runtimeName in @('libcrypto-3.dll', 'libssl-3.dll')) {
|
|
101
|
+
if (-not (Test-Path -LiteralPath (Join-Path $pythonRoot "DLLs\$runtimeName") -PathType Leaf)) {
|
|
102
|
+
throw "The official CPython runtime is missing its classified OpenSSL library: $runtimeName"
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
"CALIBRATE_PRO_RELEASE_PYTHON=$python" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
|
|
106
|
+
- name: Install the pinned host verification environment
|
|
107
|
+
run: |
|
|
108
|
+
& $env:CALIBRATE_PRO_RELEASE_PYTHON -m pip install --disable-pip-version-check --require-hashes -r packaging/requirements-win64-py312.lock
|
|
109
|
+
& $env:CALIBRATE_PRO_RELEASE_PYTHON -m pip install --disable-pip-version-check pytest==9.0.3
|
|
110
|
+
- name: Install the pinned Inno Setup compiler
|
|
111
|
+
shell: pwsh
|
|
112
|
+
run: |
|
|
113
|
+
$installer = Join-Path $env:RUNNER_TEMP 'innosetup-6.7.3.exe'
|
|
114
|
+
$innoRoot = Join-Path $env:RUNNER_TEMP 'inno-6.7.3'
|
|
115
|
+
Invoke-WebRequest -Uri 'https://github.com/jrsoftware/issrc/releases/download/is-6_7_3/innosetup-6.7.3.exe' -OutFile $installer
|
|
116
|
+
$expectedInstaller = '9c73c3bae7ed48d44112a0f48e66742c00090bdb5bef71d9d3c056c66e97b732'
|
|
117
|
+
$actualInstaller = (Get-FileHash -LiteralPath $installer -Algorithm SHA256).Hash.ToLowerInvariant()
|
|
118
|
+
if ($actualInstaller -ne $expectedInstaller) { throw "Unexpected Inno installer hash: $actualInstaller" }
|
|
119
|
+
$signature = Get-AuthenticodeSignature -LiteralPath $installer
|
|
120
|
+
if ($signature.Status -ne 'Valid') { throw "Inno installer signature is not valid: $($signature.Status)" }
|
|
121
|
+
$innoInstall = Start-Process -FilePath $installer `
|
|
122
|
+
-ArgumentList @('/VERYSILENT', '/SUPPRESSMSGBOXES', '/NORESTART', '/CURRENTUSER', "/DIR=$innoRoot") `
|
|
123
|
+
-Wait -PassThru -WindowStyle Hidden
|
|
124
|
+
if ($innoInstall.ExitCode -ne 0) { throw "Inno installation failed: $($innoInstall.ExitCode)" }
|
|
125
|
+
$iscc = Join-Path $innoRoot 'ISCC.exe'
|
|
126
|
+
if (-not (Test-Path -LiteralPath $iscc -PathType Leaf)) { throw 'ISCC.exe was not installed' }
|
|
127
|
+
"CALIBRATE_PRO_ISCC=$iscc" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
|
|
128
|
+
- name: Build and verify the complete unsigned Windows candidate
|
|
129
|
+
shell: pwsh
|
|
130
|
+
run: ./scripts/build_windows.ps1 -Unsigned -OutputRoot (Join-Path $env:RUNNER_TEMP 'calibrate-release')
|
|
131
|
+
- name: Verify unsigned reproducibility
|
|
132
|
+
shell: pwsh
|
|
133
|
+
run: ./scripts/verify_reproducibility.ps1
|
|
134
|
+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
|
135
|
+
with:
|
|
136
|
+
name: windows-release-candidate
|
|
137
|
+
path: ${{ runner.temp }}\calibrate-release\release\
|
|
138
|
+
if-no-files-found: error
|
|
139
|
+
|
|
140
|
+
verify-publish-assets:
|
|
141
|
+
if: github.event_name == 'release' || inputs.publish
|
|
142
|
+
needs: [candidate, windows-candidate]
|
|
143
|
+
runs-on: ubuntu-latest
|
|
144
|
+
permissions:
|
|
145
|
+
actions: read
|
|
146
|
+
contents: read
|
|
147
|
+
steps:
|
|
148
|
+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
|
149
|
+
with:
|
|
150
|
+
ref: ${{ github.event_name == 'release' && github.event.release.tag_name || inputs.release_tag }}
|
|
151
|
+
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
|
|
152
|
+
with:
|
|
153
|
+
python-version: "3.12"
|
|
154
|
+
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
155
|
+
with:
|
|
156
|
+
name: windows-release-candidate
|
|
157
|
+
path: windows-candidate
|
|
158
|
+
- name: Download the exact accepted GitHub release assets
|
|
159
|
+
env:
|
|
160
|
+
GH_TOKEN: ${{ github.token }}
|
|
161
|
+
RELEASE_TAG: ${{ github.event_name == 'release' && github.event.release.tag_name || inputs.release_tag }}
|
|
162
|
+
run: gh release download "$RELEASE_TAG" --dir accepted --repo "$GITHUB_REPOSITORY"
|
|
163
|
+
- name: Verify the accepted release-asset hashes
|
|
164
|
+
working-directory: accepted
|
|
165
|
+
run: sha256sum --check SHA256SUMS.txt
|
|
166
|
+
- name: Verify the exact accepted release-asset set
|
|
167
|
+
run: |
|
|
168
|
+
python scripts/verify_release_asset_set.py accepted
|
|
169
|
+
python scripts/verify_release_asset_set.py windows-candidate
|
|
170
|
+
- name: Match accepted Python distributions to the tag-built Windows candidate
|
|
171
|
+
env:
|
|
172
|
+
RELEASE_TAG: ${{ github.event_name == 'release' && github.event.release.tag_name || inputs.release_tag }}
|
|
173
|
+
run: |
|
|
174
|
+
test "$RELEASE_TAG" = "v1.1.0"
|
|
175
|
+
cmp --silent accepted/calibrate_pro-1.1.0-py3-none-any.whl windows-candidate/calibrate_pro-1.1.0-py3-none-any.whl
|
|
176
|
+
cmp --silent accepted/calibrate_pro-1.1.0.tar.gz windows-candidate/calibrate_pro-1.1.0.tar.gz
|
|
177
|
+
mkdir pypi-dist
|
|
178
|
+
cp accepted/calibrate_pro-1.1.0-py3-none-any.whl pypi-dist/
|
|
179
|
+
cp accepted/calibrate_pro-1.1.0.tar.gz pypi-dist/
|
|
180
|
+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
|
181
|
+
with:
|
|
182
|
+
name: verified-pypi-distributions
|
|
183
|
+
path: pypi-dist/
|
|
184
|
+
if-no-files-found: error
|
|
185
|
+
retention-days: 1
|
|
186
|
+
|
|
187
|
+
publish:
|
|
188
|
+
if: github.event_name == 'release' || inputs.publish
|
|
189
|
+
needs: verify-publish-assets
|
|
190
|
+
runs-on: ubuntu-latest
|
|
191
|
+
environment: pypi
|
|
192
|
+
permissions:
|
|
193
|
+
actions: read
|
|
194
|
+
id-token: write
|
|
195
|
+
steps:
|
|
196
|
+
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
197
|
+
with:
|
|
198
|
+
name: verified-pypi-distributions
|
|
199
|
+
path: pypi-dist
|
|
200
|
+
- name: Publish verified distributions to PyPI
|
|
201
|
+
uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # release/v1
|
|
202
|
+
with:
|
|
203
|
+
packages-dir: pypi-dist/
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
Calibrate Pro 1.1 separates color computation, workflow policy, user confirmation, and
|
|
4
|
+
Windows display actuation. The central rule is simple: application-facing code can
|
|
5
|
+
propose a display change, but only the confirmation coordinator and canonical Windows
|
|
6
|
+
adapter can execute it.
|
|
7
|
+
|
|
8
|
+
## Layers
|
|
9
|
+
|
|
10
|
+
```text
|
|
11
|
+
calibrate_pro/
|
|
12
|
+
core/ color math, profiles, LUT generation, transforms
|
|
13
|
+
targets/ SDR/HDR calibration target definitions
|
|
14
|
+
panels/ characterized-panel data and read-only detection
|
|
15
|
+
calibration/ instrument measurement and calibration algorithms
|
|
16
|
+
sensorless/ characterization-derived estimation algorithms
|
|
17
|
+
verification/ evidence types, patch analysis, reports, PDF export
|
|
18
|
+
|
|
19
|
+
workflow.py pure six-stage state machine and immutable ApplyPlan
|
|
20
|
+
actuation.py one-use confirmation and transaction coordination
|
|
21
|
+
recovery.py transaction phases, compensation, and receipts
|
|
22
|
+
diagnostics.py deterministic, read-only installation report
|
|
23
|
+
runtime.py source/frozen resource resolution
|
|
24
|
+
|
|
25
|
+
adapters/
|
|
26
|
+
windows_display_state.py
|
|
27
|
+
canonical DDC/CI, ICC, VCGT, and DWM write boundary
|
|
28
|
+
|
|
29
|
+
gui/ PySide6 presentation; emits proposals, never raw writes
|
|
30
|
+
commands/ unelevated desktop/HDR launch and read-only doctor command
|
|
31
|
+
main.py read-only CLI dispatch and proposal-only legacy names
|
|
32
|
+
frozen_main.py two frozen executable entry points
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Low-level Windows modules still contain native API wrappers. Application code cannot
|
|
36
|
+
import or call their writer primitives directly; `DefaultWindowsDisplayAdapter` is the
|
|
37
|
+
sole production bridge from a confirmed transaction to those wrappers.
|
|
38
|
+
|
|
39
|
+
## Workflow
|
|
40
|
+
|
|
41
|
+
The user-visible state machine is:
|
|
42
|
+
|
|
43
|
+
```text
|
|
44
|
+
Detect -> Method -> Preview -> Apply -> Verify -> Save/Report
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
1. Detection gathers display identity and capability information without granting write
|
|
48
|
+
authority.
|
|
49
|
+
2. Method selection chooses sensorless or measured evidence.
|
|
50
|
+
3. Preview constructs an immutable `ApplyPlan`. External ICC, VCGT, and DWM inputs are
|
|
51
|
+
bounded and bound to the plan by SHA-256.
|
|
52
|
+
4. Confirmation is consumed once. The coordinator revalidates capabilities and hands an
|
|
53
|
+
opaque authorization to the adapter while holding the apply gate.
|
|
54
|
+
5. The adapter captures the requested prior state, applies the sealed plan, and reads the
|
|
55
|
+
result back. A failure invokes compensation and verifies that compensation before it
|
|
56
|
+
reports restoration.
|
|
57
|
+
6. Verification and reports preserve the evidence kind and source of every performance
|
|
58
|
+
metric.
|
|
59
|
+
|
|
60
|
+
Rejecting, expiring, copying, substituting, or mutating a plan does not authorize a
|
|
61
|
+
write. Legacy mutation-capable CLI names are proposal-only and return without changing
|
|
62
|
+
display state.
|
|
63
|
+
|
|
64
|
+
## Capability and recovery model
|
|
65
|
+
|
|
66
|
+
`CapabilityState` distinguishes sensor, DDC/CI, DWM write, authoritative DWM capture,
|
|
67
|
+
ICC association, and VCGT capabilities. A requested operation is disabled unless its
|
|
68
|
+
capability is positively present. In particular, DWM application requires both write
|
|
69
|
+
support and authoritative prior-state capture; process-local LUT memory is not accepted
|
|
70
|
+
as evidence of operating-system state.
|
|
71
|
+
|
|
72
|
+
Transactions use per-display process and Windows named mutexes. ICC content-addressed
|
|
73
|
+
cache operations also use a digest-scoped mutex and native file lease. Native resources
|
|
74
|
+
remain registered until cleanup is positively known, and uncertain outcomes fail closed.
|
|
75
|
+
Recovery is an in-process compensating transaction rather than a promise of crash-safe
|
|
76
|
+
rollback across power loss or operating-system termination.
|
|
77
|
+
|
|
78
|
+
## Evidence model
|
|
79
|
+
|
|
80
|
+
Performance fields cross the report boundary as `MetricValue`, not bare numbers. Each is
|
|
81
|
+
labelled `measured`, `estimated`, `simulated`, `replayed`, or `not_measured`, and numeric
|
|
82
|
+
values retain a source receipt. Sensorless computation can inform a plan, but it does not
|
|
83
|
+
become an observation of the attached display.
|
|
84
|
+
|
|
85
|
+
## Entry points
|
|
86
|
+
|
|
87
|
+
- `CalibratePro.exe` / `calibrate-pro gui`: main PySide6 workflow.
|
|
88
|
+
- `CalibrateProCLI.exe`: frozen `doctor`, `gui`, and `hdr` dispatcher; `hdr` opens the
|
|
89
|
+
HDR target/proposal workflow.
|
|
90
|
+
- `calibrate-pro doctor [--json]`: deterministic, read-only installation diagnostics.
|
|
91
|
+
- `list-targets`, `list-panels`, `info`, `hdr-status`, `patterns`, and `plugins`:
|
|
92
|
+
read-only or visual-inspection utilities.
|
|
93
|
+
- Tray and calibration guard: monitor-and-notify only in 1.1.
|
|
94
|
+
|
|
95
|
+
Both frozen executables use `asInvoker`; the installer is per-user and lowest privilege.
|
|
96
|
+
|
|
97
|
+
## Release architecture
|
|
98
|
+
|
|
99
|
+
The Windows release uses one PyInstaller analysis and two onedir executables. An exact
|
|
100
|
+
first-party/distribution allowlist, Qt-component policy, component-to-notice policy, and
|
|
101
|
+
source-provenance lock fail closed on unknown staged content. The build produces a
|
|
102
|
+
portable ZIP, per-user installer, wheel, analysis/manifest/smoke receipts, and sorted
|
|
103
|
+
SHA-256 inventory from a hash-locked environment.
|
|
104
|
+
|
|
105
|
+
## Verification
|
|
106
|
+
|
|
107
|
+
Tests cover the pure color/HDR core, workflow state machine, confirmation and recovery,
|
|
108
|
+
Windows API contracts, native-resource lifecycle, least-privilege boundary, GUI
|
|
109
|
+
truthfulness, Qt selection, frozen module closure, redistribution notices, and release
|
|
110
|
+
artifact construction. Publication additionally requires frozen offscreen smoke tests,
|
|
111
|
+
PE manifest inspection, component/source audits, and a clean install proof.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## v1.1.0 (2026-07-11)
|
|
4
|
+
|
|
5
|
+
- Updated GitHub Actions workflows to current checkout/setup-python majors.
|
|
6
|
+
- Added the documented `test` extra so `pip install -e ".[test]"` works.
|
|
7
|
+
- Normalized scanner-blocking dash punctuation in public docs and developer-facing strings.
|
|
8
|
+
- Project Telos presentation and operator-surface pass: README hero, brand assets under `docs/brand/`, cross-flagship navigation, and Current status / Operator surface blocks.
|
|
9
|
+
- Documented the operator surface across the PySide6 desktop workflow and read-only CLI.
|
|
10
|
+
- Relicensed to the FSL-1.1-MIT as part of Project Telos flagship promotion.
|
|
11
|
+
- Migrated the desktop runtime and Build UI integration to PySide6.
|
|
12
|
+
- Added the explicit Detect -> Method -> Preview -> Apply -> Verify -> Save/Report workflow.
|
|
13
|
+
- Consolidated display mutation behind one confirmation-bound Windows adapter; legacy
|
|
14
|
+
direct-action CLI commands are proposal-only in 1.1.
|
|
15
|
+
- Added immutable, SHA-256-bound apply plans, bounded inputs, prior-state capture,
|
|
16
|
+
compensating recovery, authoritative read-back, and concurrency/resource-lifecycle
|
|
17
|
+
gates.
|
|
18
|
+
- Removed automatic GUI, tray, guard, and startup actuator paths; packaged entry points
|
|
19
|
+
launch unelevated.
|
|
20
|
+
- Added measured/estimated/simulated/replayed/Not measured provenance throughout the GUI
|
|
21
|
+
and report paths; removed seeded or unsupported observations.
|
|
22
|
+
- Added read-only `doctor` diagnostics with stable JSON output.
|
|
23
|
+
- Added hash-locked Windows builds, exact frozen-module auditing, third-party notices and
|
|
24
|
+
source provenance, PE-manifest checks, per-user installer/portable packaging, and
|
|
25
|
+
frozen smoke/reproducibility verification.
|
|
26
|
+
|
|
27
|
+
## v1.0.0 (2026-03-22)
|
|
28
|
+
|
|
29
|
+
### Features
|
|
30
|
+
- **58-panel database** with DDC/CI recommendations for QD-OLED, WOLED, IPS, VA, Mini-LED, and RGB OLED panels
|
|
31
|
+
- **Sensorless calibration** using panel-specific characterization data and Bradford chromatic adaptation
|
|
32
|
+
- **Hardware calibration** via DDC/CI: brightness, contrast, RGB gain/offset, gamma
|
|
33
|
+
- **i1Display3 native USB driver** with CCMX spectral correction (44% dE improvement on QD-OLED)
|
|
34
|
+
- **3D LUT generation** (33x33x33) with 6 gamut mapping algorithms including CAM16 and Jzazbz
|
|
35
|
+
- **13 calibration targets**: Rec.709, DCI-P3, HDR10, Netflix SDR/HDR, EBU Grade 1, and more
|
|
36
|
+
- **12 verification patch sets** (287 patches): grayscale, saturation sweeps, SMPTE/EBU bars, skin tones
|
|
37
|
+
- **LUT export formats**: .cube, .3dl, .clf (ACES), .mga, .csp, ReShade, SpecialK, OBS, mpv, MadVR, ICC v4
|
|
38
|
+
- **CCSS/CCMX import** for community spectral corrections
|
|
39
|
+
- **CalibrationGuard** watchdog (15-second polling) prevents Windows from resetting calibration
|
|
40
|
+
- **DwmLutGUI integration** with automatic elevation for system-wide 3D LUT
|
|
41
|
+
- **PyQt6 GUI** with warm pastel theme, CIE chromaticity diagram, system tray, toast notifications
|
|
42
|
+
- **CLI** with 26 commands for headless calibration workflows
|
|
43
|
+
|
|
44
|
+
### Platform Support
|
|
45
|
+
- Windows 10/11: Full support
|
|
46
|
+
- macOS: Planned (stubs exist)
|
|
47
|
+
- Linux: Planned (stubs exist)
|
|
48
|
+
|
|
49
|
+
### Tests
|
|
50
|
+
- 197 tests passing
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
This repository is part of the Project Telos public surface. Keep changes small, tested, and easy for public users and developers to verify.
|
|
4
|
+
|
|
5
|
+
Before sending a change:
|
|
6
|
+
|
|
7
|
+
- Read `README.md` and any local `AGENTS.md` instructions.
|
|
8
|
+
- Run the narrowest test or verification command that covers the change.
|
|
9
|
+
- Keep examples, package metadata, and public claims aligned with current behavior.
|
|
10
|
+
- Do not commit secrets, `.env` files, private corpus material, or generated caches.
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Functional Source License, Version 1.1, MIT Future License
|
|
2
|
+
|
|
3
|
+
## Abbreviation
|
|
4
|
+
|
|
5
|
+
FSL-1.1-MIT
|
|
6
|
+
|
|
7
|
+
## Notice
|
|
8
|
+
|
|
9
|
+
Copyright 2026 Zain Dana Harper
|
|
10
|
+
|
|
11
|
+
## Terms and Conditions
|
|
12
|
+
|
|
13
|
+
### Licensor ("We")
|
|
14
|
+
|
|
15
|
+
The party offering the Software under these Terms and Conditions.
|
|
16
|
+
|
|
17
|
+
### The Software
|
|
18
|
+
|
|
19
|
+
The "Software" is each version of the software that we make available under
|
|
20
|
+
these Terms and Conditions, as indicated by our inclusion of these Terms and
|
|
21
|
+
Conditions with the Software.
|
|
22
|
+
|
|
23
|
+
### License Grant
|
|
24
|
+
|
|
25
|
+
Subject to your compliance with this License Grant and the Patents,
|
|
26
|
+
Redistribution and Trademark clauses below, we hereby grant you the right to
|
|
27
|
+
use, copy, modify, create derivative works, publicly perform, publicly display
|
|
28
|
+
and redistribute the Software for any Permitted Purpose identified below.
|
|
29
|
+
|
|
30
|
+
### Permitted Purpose
|
|
31
|
+
|
|
32
|
+
A Permitted Purpose is any purpose other than a Competing Use. A Competing Use
|
|
33
|
+
means making the Software available to others in a commercial product or
|
|
34
|
+
service that:
|
|
35
|
+
|
|
36
|
+
1. substitutes for the Software;
|
|
37
|
+
|
|
38
|
+
2. substitutes for any other product or service we offer using the Software
|
|
39
|
+
that exists as of the date we make the Software available; or
|
|
40
|
+
|
|
41
|
+
3. offers the same or substantially similar functionality as the Software.
|
|
42
|
+
|
|
43
|
+
Permitted Purposes specifically include using the Software:
|
|
44
|
+
|
|
45
|
+
1. for your internal use and access;
|
|
46
|
+
|
|
47
|
+
2. for non-commercial education;
|
|
48
|
+
|
|
49
|
+
3. for non-commercial research; and
|
|
50
|
+
|
|
51
|
+
4. in connection with professional services that you provide to a licensee
|
|
52
|
+
using the Software in accordance with these Terms and Conditions.
|
|
53
|
+
|
|
54
|
+
### Patents
|
|
55
|
+
|
|
56
|
+
To the extent your use for a Permitted Purpose would necessarily infringe our
|
|
57
|
+
patents, the license grant above includes a license under our patents. If you
|
|
58
|
+
make a claim against any party that the Software infringes or contributes to
|
|
59
|
+
the infringement of any patent, then your patent license to the Software ends
|
|
60
|
+
immediately.
|
|
61
|
+
|
|
62
|
+
### Redistribution
|
|
63
|
+
|
|
64
|
+
The Terms and Conditions apply to all copies, modifications and derivatives of
|
|
65
|
+
the Software.
|
|
66
|
+
|
|
67
|
+
If you redistribute any copies, modifications or derivatives of the Software,
|
|
68
|
+
you must include a copy of or a link to these Terms and Conditions and not
|
|
69
|
+
remove any copyright notices provided in or with the Software.
|
|
70
|
+
|
|
71
|
+
### Disclaimer
|
|
72
|
+
|
|
73
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR
|
|
74
|
+
IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF FITNESS FOR A PARTICULAR
|
|
75
|
+
PURPOSE, MERCHANTABILITY, TITLE OR NON-INFRINGEMENT.
|
|
76
|
+
|
|
77
|
+
IN NO EVENT WILL WE HAVE ANY LIABILITY TO YOU ARISING OUT OF OR RELATED TO THE
|
|
78
|
+
SOFTWARE, INCLUDING INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES,
|
|
79
|
+
EVEN IF WE HAVE BEEN INFORMED OF THEIR POSSIBILITY IN ADVANCE.
|
|
80
|
+
|
|
81
|
+
### Trademarks
|
|
82
|
+
|
|
83
|
+
Except for displaying the License Details and identifying us as the origin of
|
|
84
|
+
the Software, you have no right under these Terms and Conditions to use our
|
|
85
|
+
trademarks, trade names, service marks or product names.
|
|
86
|
+
|
|
87
|
+
## Grant of Future License
|
|
88
|
+
|
|
89
|
+
We hereby irrevocably grant you an additional license to use the Software under
|
|
90
|
+
the MIT license that is effective on the second anniversary of the date we make
|
|
91
|
+
the Software available. On or after that date, you may use the Software under
|
|
92
|
+
the MIT license, in which case the following will apply:
|
|
93
|
+
|
|
94
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
95
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
96
|
+
the Software without restriction, including without limitation the rights to
|
|
97
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
98
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
|
99
|
+
so, subject to the following conditions:
|
|
100
|
+
|
|
101
|
+
The above copyright notice and this permission notice shall be included in all
|
|
102
|
+
copies or substantial portions of the Software.
|
|
103
|
+
|
|
104
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
105
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
106
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
107
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
108
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
109
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
110
|
+
SOFTWARE.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
include LICENSE
|
|
2
|
+
include README.md
|
|
3
|
+
include ARCHITECTURE.md
|
|
4
|
+
include AUTHORS.md
|
|
5
|
+
include CHANGELOG.md
|
|
6
|
+
include CONTRIBUTING.md
|
|
7
|
+
include RELEASE_NOTES.md
|
|
8
|
+
include SECURITY.md
|
|
9
|
+
include USAGE.md
|
|
10
|
+
include pyproject.toml
|
|
11
|
+
include calibrate-pro.spec
|
|
12
|
+
|
|
13
|
+
recursive-include calibrate_pro *.py *.ico *.png
|
|
14
|
+
recursive-include tests *.py *.json
|
|
15
|
+
recursive-include packaging *.json *.lock *.in *.py
|
|
16
|
+
recursive-include scripts *.py *.ps1
|
|
17
|
+
recursive-include installer *.iss
|
|
18
|
+
recursive-include THIRD_PARTY_LICENSES *
|
|
19
|
+
recursive-include dwm_lut *
|
|
20
|
+
recursive-include docs *
|
|
21
|
+
recursive-include examples *.py
|
|
22
|
+
recursive-include .github *.yml *.yaml
|
|
23
|
+
|
|
24
|
+
global-exclude *.pyc
|
|
25
|
+
global-exclude __pycache__
|
|
26
|
+
prune build
|
|
27
|
+
prune dist
|
|
28
|
+
prune release
|
|
29
|
+
prune .mypy_cache
|
|
30
|
+
prune .pytest_cache
|
|
31
|
+
prune .ruff_cache
|