davinci-resolve-mcp 2.57.4 → 2.58.0
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.
- package/AGENTS.md +20 -0
- package/CHANGELOG.md +197 -2
- package/LICENSE +1 -1
- package/README.md +73 -1
- package/bin/davinci-resolve-advanced-mcp.mjs +20 -0
- package/docs/README.md +19 -0
- package/docs/SKILL.md +62 -1
- package/docs/contributing.md +1 -1
- package/docs/guides/control-panel.md +9 -0
- package/docs/kernels/README.md +21 -0
- package/docs/kernels/audio-fairlight-kernel.md +22 -0
- package/docs/kernels/color-grade-kernel.md +51 -0
- package/docs/kernels/fusion-composition-kernel.md +17 -0
- package/docs/kernels/media-pool-ingest-kernel.md +20 -0
- package/docs/kernels/render-deliver-kernel.md +32 -0
- package/docs/kernels/timeline-conform-interchange-kernel.md +39 -0
- package/docs/kernels/timeline-edit-kernel.md +17 -0
- package/docs/process/release-process.md +29 -7
- package/docs/reference/api-coverage.md +1 -1
- package/docs/reference/api-limitations.md +38 -1
- package/install.py +27 -4
- package/package.json +23 -2
- package/resolve-advanced/README.md +194 -0
- package/resolve-advanced/package.json +50 -0
- package/resolve-advanced/server/black-balance.mjs +92 -0
- package/resolve-advanced/server/capabilities.mjs +86 -0
- package/resolve-advanced/server/cdl-io.mjs +76 -0
- package/resolve-advanced/server/contrast-normalize.mjs +180 -0
- package/resolve-advanced/server/db-patch.mjs +91 -0
- package/resolve-advanced/server/deliverable-entities.mjs +86 -0
- package/resolve-advanced/server/deliverable-qc.mjs +270 -0
- package/resolve-advanced/server/editorial.mjs +370 -0
- package/resolve-advanced/server/exposure-level.mjs +129 -0
- package/resolve-advanced/server/extract-frames.mjs +196 -0
- package/resolve-advanced/server/ffprobe-media.mjs +88 -0
- package/resolve-advanced/server/gamut-legal.mjs +112 -0
- package/resolve-advanced/server/grade-body-patch.mjs +246 -0
- package/resolve-advanced/server/grade-transfer.mjs +66 -0
- package/resolve-advanced/server/group-grade-read.mjs +137 -0
- package/resolve-advanced/server/index.mjs +105 -0
- package/resolve-advanced/server/lib.mjs +84 -0
- package/resolve-advanced/server/libs.mjs +65 -0
- package/resolve-advanced/server/lineage-db.mjs +479 -0
- package/resolve-advanced/server/lut-apply.mjs +61 -0
- package/resolve-advanced/server/match-to-reference.mjs +173 -0
- package/resolve-advanced/server/media-inventory.mjs +169 -0
- package/resolve-advanced/server/media-ops.mjs +243 -0
- package/resolve-advanced/server/node-meta-db.mjs +62 -0
- package/resolve-advanced/server/node-provenance.mjs +102 -0
- package/resolve-advanced/server/offline-ref-db.mjs +420 -0
- package/resolve-advanced/server/offline-ref.mjs +179 -0
- package/resolve-advanced/server/project-db.mjs +233 -0
- package/resolve-advanced/server/provenance-audit.mjs +210 -0
- package/resolve-advanced/server/qc-frame.mjs +224 -0
- package/resolve-advanced/server/qc-sampler.mjs +67 -0
- package/resolve-advanced/server/readback.mjs +77 -0
- package/resolve-advanced/server/render-manifest.mjs +93 -0
- package/resolve-advanced/server/reverse-clip-db.mjs +270 -0
- package/resolve-advanced/server/runner-apply-contract.mjs +64 -0
- package/resolve-advanced/server/runner.mjs +244 -0
- package/resolve-advanced/server/saturation-match.mjs +108 -0
- package/resolve-advanced/server/scope-read.mjs +257 -0
- package/resolve-advanced/server/season-look.mjs +96 -0
- package/resolve-advanced/server/shot-intent.mjs +82 -0
- package/resolve-advanced/server/shot-match.mjs +147 -0
- package/resolve-advanced/server/skin-match.mjs +205 -0
- package/resolve-advanced/server/spec-compile.mjs +217 -0
- package/resolve-advanced/server/tone-curve-transfer.mjs +184 -0
- package/resolve-advanced/server/tool-catalog.mjs +265 -0
- package/resolve-advanced/server/tools/audio.mjs +54 -0
- package/resolve-advanced/server/tools/audio_plan.mjs +58 -0
- package/resolve-advanced/server/tools/capabilities.mjs +16 -0
- package/resolve-advanced/server/tools/color_trace.mjs +165 -0
- package/resolve-advanced/server/tools/conform.mjs +291 -0
- package/resolve-advanced/server/tools/deliverable.mjs +105 -0
- package/resolve-advanced/server/tools/drp.mjs +232 -0
- package/resolve-advanced/server/tools/drt.mjs +200 -0
- package/resolve-advanced/server/tools/drx.mjs +943 -0
- package/resolve-advanced/server/tools/editorial.mjs +69 -0
- package/resolve-advanced/server/tools/fairlight.mjs +108 -0
- package/resolve-advanced/server/tools/fusion.mjs +64 -0
- package/resolve-advanced/server/tools/media.mjs +102 -0
- package/resolve-advanced/server/tools/offline_ref.mjs +123 -0
- package/resolve-advanced/server/tools/pipeline.mjs +137 -0
- package/resolve-advanced/server/tools/project_db.mjs +200 -0
- package/resolve-advanced/server/tools/project_read.mjs +212 -0
- package/resolve-advanced/server/tools/provenance.mjs +73 -0
- package/resolve-advanced/server/verify-grade.mjs +113 -0
- package/resolve-advanced/server/white-balance-match.mjs +122 -0
- package/resolve-advanced/vendor/audio/format-converter.js +330 -0
- package/resolve-advanced/vendor/audio/split.js +173 -0
- package/resolve-advanced/vendor/audio/trim.js +188 -0
- package/resolve-advanced/vendor/audio-fairlight/index.js +391 -0
- package/resolve-advanced/vendor/conform-qc/adapters/frame-sampler.js +56 -0
- package/resolve-advanced/vendor/conform-qc/adapters/local-ffmpeg-sampler.js +65 -0
- package/resolve-advanced/vendor/conform-qc/adapters/rendernode-ffmpeg-sampler.js +50 -0
- package/resolve-advanced/vendor/conform-qc/adapters/resolve/driver.py +176 -0
- package/resolve-advanced/vendor/conform-qc/adapters/resolve-driver.js +61 -0
- package/resolve-advanced/vendor/conform-qc/adapters/resolve-headless-driver.js +86 -0
- package/resolve-advanced/vendor/conform-qc/adapters/vision-validator.js +75 -0
- package/resolve-advanced/vendor/conform-qc/cli.js +63 -0
- package/resolve-advanced/vendor/conform-qc/compare/advisory.js +106 -0
- package/resolve-advanced/vendor/conform-qc/compare/decode.js +36 -0
- package/resolve-advanced/vendor/conform-qc/compare/index.js +61 -0
- package/resolve-advanced/vendor/conform-qc/compare/locate.js +70 -0
- package/resolve-advanced/vendor/conform-qc/compare/metrics.js +409 -0
- package/resolve-advanced/vendor/conform-qc/docs/runbook.md +72 -0
- package/resolve-advanced/vendor/conform-qc/index.js +49 -0
- package/resolve-advanced/vendor/conform-qc/knowledge/index.js +110 -0
- package/resolve-advanced/vendor/conform-qc/ops/conform-core.js +137 -0
- package/resolve-advanced/vendor/conform-qc/ops/conform-diff.js +109 -0
- package/resolve-advanced/vendor/conform-qc/ops/insert.js +108 -0
- package/resolve-advanced/vendor/conform-qc/ops/local-conform.js +61 -0
- package/resolve-advanced/vendor/conform-qc/ops/patch.js +80 -0
- package/resolve-advanced/vendor/conform-qc/ops/trigger.js +32 -0
- package/resolve-advanced/vendor/conform-qc/ops/verify.js +105 -0
- package/resolve-advanced/vendor/conform-qc/ops/workflow.js +30 -0
- package/resolve-advanced/vendor/conform-qc/oracle/emulate.js +155 -0
- package/resolve-advanced/vendor/conform-qc/oracle/index.js +38 -0
- package/resolve-advanced/vendor/conform-qc/oracle/resolve.js +196 -0
- package/resolve-advanced/vendor/conform-qc/package.json +16 -0
- package/resolve-advanced/vendor/conform-qc/packaging/emit-aaf.js +30 -0
- package/resolve-advanced/vendor/conform-qc/packaging/emit-fcp7.js +64 -0
- package/resolve-advanced/vendor/conform-qc/packaging/index.js +169 -0
- package/resolve-advanced/vendor/conform-qc/packaging/media-ops.js +56 -0
- package/resolve-advanced/vendor/conform-qc/packaging/otio.js +50 -0
- package/resolve-advanced/vendor/conform-qc/packaging/relink.js +50 -0
- package/resolve-advanced/vendor/conform-qc/packaging/surgical-relink.js +195 -0
- package/resolve-advanced/vendor/conform-qc/parse/index.js +54 -0
- package/resolve-advanced/vendor/conform-qc/parse/merge-dto.js +27 -0
- package/resolve-advanced/vendor/conform-qc/parse/xmeml-geometry.js +256 -0
- package/resolve-advanced/vendor/conform-qc/reference/burnin-ocr.js +100 -0
- package/resolve-advanced/vendor/conform-qc/reference/sidecar.js +37 -0
- package/resolve-advanced/vendor/conform-qc/repair/analysis.js +62 -0
- package/resolve-advanced/vendor/conform-qc/repair/index.js +78 -0
- package/resolve-advanced/vendor/conform-qc/repair/media-analysis.js +139 -0
- package/resolve-advanced/vendor/conform-qc/repair/media-index.js +135 -0
- package/resolve-advanced/vendor/conform-qc/repair/strategies.js +250 -0
- package/resolve-advanced/vendor/conform-qc/report/index.js +133 -0
- package/resolve-advanced/vendor/conform-qc/roles/index.js +96 -0
- package/resolve-advanced/vendor/conform-qc/synthetic/generate.js +233 -0
- package/resolve-advanced/vendor/conform-qc/test/advisory.test.js +85 -0
- package/resolve-advanced/vendor/conform-qc/test/cli.test.js +39 -0
- package/resolve-advanced/vendor/conform-qc/test/compare.test.js +152 -0
- package/resolve-advanced/vendor/conform-qc/test/conform-diff.test.js +70 -0
- package/resolve-advanced/vendor/conform-qc/test/emulate.test.js +51 -0
- package/resolve-advanced/vendor/conform-qc/test/frame-sampler.test.js +30 -0
- package/resolve-advanced/vendor/conform-qc/test/geometry.test.js +112 -0
- package/resolve-advanced/vendor/conform-qc/test/knowledge.test.js +56 -0
- package/resolve-advanced/vendor/conform-qc/test/lifecycle.test.js +110 -0
- package/resolve-advanced/vendor/conform-qc/test/local-ffmpeg-sampler.test.js +66 -0
- package/resolve-advanced/vendor/conform-qc/test/locate.test.js +63 -0
- package/resolve-advanced/vendor/conform-qc/test/media-analysis.test.js +63 -0
- package/resolve-advanced/vendor/conform-qc/test/media-index-normalized.test.js +65 -0
- package/resolve-advanced/vendor/conform-qc/test/media-index-origin.test.js +53 -0
- package/resolve-advanced/vendor/conform-qc/test/metrics-fast.test.js +91 -0
- package/resolve-advanced/vendor/conform-qc/test/oracle-reverse.test.js +86 -0
- package/resolve-advanced/vendor/conform-qc/test/oracle.test.js +136 -0
- package/resolve-advanced/vendor/conform-qc/test/p0-acceptance.test.js +60 -0
- package/resolve-advanced/vendor/conform-qc/test/p1-acceptance.test.js +75 -0
- package/resolve-advanced/vendor/conform-qc/test/p45-patch-acceptance.test.js +102 -0
- package/resolve-advanced/vendor/conform-qc/test/packaging.test.js +133 -0
- package/resolve-advanced/vendor/conform-qc/test/parse-stubs.test.js +28 -0
- package/resolve-advanced/vendor/conform-qc/test/repair-strategies.test.js +128 -0
- package/resolve-advanced/vendor/conform-qc/test/repair.test.js +84 -0
- package/resolve-advanced/vendor/conform-qc/test/report.test.js +52 -0
- package/resolve-advanced/vendor/conform-qc/test/resolve-readback.test.js +71 -0
- package/resolve-advanced/vendor/conform-qc/test/roles.test.js +107 -0
- package/resolve-advanced/vendor/conform-qc/test/runbook.test.js +30 -0
- package/resolve-advanced/vendor/conform-qc/test/scale-residual.test.js +40 -0
- package/resolve-advanced/vendor/conform-qc/test/sidecar.test.js +51 -0
- package/resolve-advanced/vendor/conform-qc/test/smoke.test.js +87 -0
- package/resolve-advanced/vendor/conform-qc/test/surgical-relink.test.js +73 -0
- package/resolve-advanced/vendor/conform-qc/test/synthetic.test.js +98 -0
- package/resolve-advanced/vendor/conform-qc/test/verify.test.js +93 -0
- package/resolve-advanced/vendor/conform-qc/test/vision-validator.test.js +43 -0
- package/resolve-advanced/vendor/conform-qc/test/workflow-driver.test.js +46 -0
- package/resolve-advanced/vendor/conform-qc/toolset/index.js +53 -0
- package/resolve-advanced/vendor/drp-format/README.md +116 -0
- package/resolve-advanced/vendor/drp-format/__tests__/_resolve-verify.js +39 -0
- package/resolve-advanced/vendor/drp-format/__tests__/add-media-clip.test.js +30 -0
- package/resolve-advanced/vendor/drp-format/__tests__/assemble-timeline.test.js +68 -0
- package/resolve-advanced/vendor/drp-format/__tests__/author-project.test.js +57 -0
- package/resolve-advanced/vendor/drp-format/__tests__/composition-text.test.js +98 -0
- package/resolve-advanced/vendor/drp-format/__tests__/diff.test.js +272 -0
- package/resolve-advanced/vendor/drp-format/__tests__/effect-filters-compressed.test.js +143 -0
- package/resolve-advanced/vendor/drp-format/__tests__/fixtures/p0-3-session30-empty-effectfilters.drp +0 -0
- package/resolve-advanced/vendor/drp-format/__tests__/fixtures/retimed-timemap-50pct.hex +1 -0
- package/resolve-advanced/vendor/drp-format/__tests__/fixtures/retimed-timemap-dynamic.hex +1 -0
- package/resolve-advanced/vendor/drp-format/__tests__/inject-grades.test.js +238 -0
- package/resolve-advanced/vendor/drp-format/__tests__/keyed-dict.test.js +85 -0
- package/resolve-advanced/vendor/drp-format/__tests__/lut-refs.test.js +119 -0
- package/resolve-advanced/vendor/drp-format/__tests__/media-blobs.test.js +25 -0
- package/resolve-advanced/vendor/drp-format/__tests__/media-timemap.test.js +119 -0
- package/resolve-advanced/vendor/drp-format/__tests__/place-fusion-title.test.js +52 -0
- package/resolve-advanced/vendor/drp-format/__tests__/place-generator.test.js +40 -0
- package/resolve-advanced/vendor/drp-format/__tests__/place-transition.test.js +48 -0
- package/resolve-advanced/vendor/drp-format/__tests__/protobuf-wire.test.js +64 -0
- package/resolve-advanced/vendor/drp-format/__tests__/relink-media.test.js +106 -0
- package/resolve-advanced/vendor/drp-format/__tests__/splice-clips.test.js +256 -0
- package/resolve-advanced/vendor/drp-format/assemble-timeline.js +65 -0
- package/resolve-advanced/vendor/drp-format/author-project.js +118 -0
- package/resolve-advanced/vendor/drp-format/composition-text.js +213 -0
- package/resolve-advanced/vendor/drp-format/curves-encoder.js +763 -0
- package/resolve-advanced/vendor/drp-format/diff.js +310 -0
- package/resolve-advanced/vendor/drp-format/drp-packager.js +201 -0
- package/resolve-advanced/vendor/drp-format/drp-validator.js +809 -0
- package/resolve-advanced/vendor/drp-format/effect-encoder.js +640 -0
- package/resolve-advanced/vendor/drp-format/extract-lut-refs.js +119 -0
- package/resolve-advanced/vendor/drp-format/grade-encoder.example.js +133 -0
- package/resolve-advanced/vendor/drp-format/grade-encoder.js +401 -0
- package/resolve-advanced/vendor/drp-format/grade-encoder.test.js +171 -0
- package/resolve-advanced/vendor/drp-format/grade-encoder.verify.js +249 -0
- package/resolve-advanced/vendor/drp-format/grade-node-extractor.js +495 -0
- package/resolve-advanced/vendor/drp-format/grade-parameter-decoder.js +774 -0
- package/resolve-advanced/vendor/drp-format/index.js +174 -0
- package/resolve-advanced/vendor/drp-format/inject-grades.js +219 -0
- package/resolve-advanced/vendor/drp-format/keyed-dict.js +227 -0
- package/resolve-advanced/vendor/drp-format/marker-encoder.js +532 -0
- package/resolve-advanced/vendor/drp-format/media-blobs.js +53 -0
- package/resolve-advanced/vendor/drp-format/media-timemap.js +164 -0
- package/resolve-advanced/vendor/drp-format/mp-folder-builder.js +293 -0
- package/resolve-advanced/vendor/drp-format/node-tree-encoder.js +1246 -0
- package/resolve-advanced/vendor/drp-format/package.json +18 -0
- package/resolve-advanced/vendor/drp-format/place-fusion-title.js +131 -0
- package/resolve-advanced/vendor/drp-format/place-generator.js +77 -0
- package/resolve-advanced/vendor/drp-format/place-transition.js +91 -0
- package/resolve-advanced/vendor/drp-format/power-window-encoder.js +776 -0
- package/resolve-advanced/vendor/drp-format/protobuf-wire.js +111 -0
- package/resolve-advanced/vendor/drp-format/qualifier-encoder.js +706 -0
- package/resolve-advanced/vendor/drp-format/relink-media.js +218 -0
- package/resolve-advanced/vendor/drp-format/rich-title-encoder.js +447 -0
- package/resolve-advanced/vendor/drp-format/seq-container-builder.js +572 -0
- package/resolve-advanced/vendor/drp-format/seq-surgery.js +155 -0
- package/resolve-advanced/vendor/drp-format/splice-clips.js +445 -0
- package/resolve-advanced/vendor/drp-format/templates/empty-project.drp +0 -0
- package/resolve-advanced/vendor/drp-format/templates/fusion-title.xml +56 -0
- package/resolve-advanced/vendor/drp-format/templates/generator-solid-color.xml +21 -0
- package/resolve-advanced/vendor/drp-format/templates/media-clip-h264.drp +0 -0
- package/resolve-advanced/vendor/drp-format/templates/transition-cross-dissolve.xml +22 -0
- package/resolve-advanced/vendor/drp-format/tool-registry.descriptor.js +80 -0
- package/resolve-advanced/vendor/drp-format/utils/safe-archive.js +54 -0
- package/resolve-advanced/vendor/drp-format/xml-builder.js +759 -0
- package/resolve-advanced/vendor/drt-format/__tests__/_resolve-verify.js +21 -0
- package/resolve-advanced/vendor/drt-format/__tests__/build.test.js +113 -0
- package/resolve-advanced/vendor/drt-format/__tests__/multi-format.test.js +93 -0
- package/resolve-advanced/vendor/drt-format/__tests__/parse-real-resolve21.test.js +51 -0
- package/resolve-advanced/vendor/drt-format/__tests__/parse.test.js +134 -0
- package/resolve-advanced/vendor/drt-format/__tests__/resolve-versions.test.js +120 -0
- package/resolve-advanced/vendor/drt-format/__tests__/schema-fingerprint.test.js +62 -0
- package/resolve-advanced/vendor/drt-format/__tests__/smoke.test.js +27 -0
- package/resolve-advanced/vendor/drt-format/__tests__/validate.test.js +109 -0
- package/resolve-advanced/vendor/drt-format/capabilities.js +69 -0
- package/resolve-advanced/vendor/drt-format/capability-domains.js +56 -0
- package/resolve-advanced/vendor/drt-format/drt-builder.js +42 -0
- package/resolve-advanced/vendor/drt-format/drt-parser.js +164 -0
- package/resolve-advanced/vendor/drt-format/drt-validator.js +98 -0
- package/resolve-advanced/vendor/drt-format/index.js +45 -0
- package/resolve-advanced/vendor/drt-format/package.json +17 -0
- package/resolve-advanced/vendor/drt-format/resolve-versions.js +153 -0
- package/resolve-advanced/vendor/drt-format/schema-fingerprint.js +74 -0
- package/resolve-advanced/vendor/drt-format/templates/drt-project-shell.xml +124 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/curves-roundtrip.test.js +148 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p2-1-face-refinement.drx +58 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p2-1-filmgrain.drx +58 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p2-1-glow.drx +58 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p2-1-lens-flare.drx +58 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p2-3-beauty-25.drx +58 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p2-3-beauty-75.drx +58 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p5-1-node-no-lut.drx +58 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p5-1-node-with-lut.drx +58 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/hsl-curves-roundtrip.test.js +117 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/lut-refs-roundtrip.test.js +112 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/matte-roundtrip.test.js +167 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/ofx-roundtrip.test.js +215 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/ofx-slugs-discovery.test.js +149 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/power-window-roundtrip.test.js +230 -0
- package/resolve-advanced/vendor/drx-codec/__tests__/qualifier-roundtrip.test.js +226 -0
- package/resolve-advanced/vendor/drx-codec/cdl-exporter.js +470 -0
- package/resolve-advanced/vendor/drx-codec/color-nlp-parser.js +833 -0
- package/resolve-advanced/vendor/drx-codec/data/color-nlp-action-mappings.json +2232 -0
- package/resolve-advanced/vendor/drx-codec/drx-generator.js +4123 -0
- package/resolve-advanced/vendor/drx-codec/drx-merger.js +320 -0
- package/resolve-advanced/vendor/drx-codec/drx-parser.js +1808 -0
- package/resolve-advanced/vendor/drx-codec/extract-custom-curves.js +215 -0
- package/resolve-advanced/vendor/drx-codec/extract-hsl-curves.js +180 -0
- package/resolve-advanced/vendor/drx-codec/extract-lut-refs.js +158 -0
- package/resolve-advanced/vendor/drx-codec/extract-matte-finesse.js +83 -0
- package/resolve-advanced/vendor/drx-codec/extract-ofx-params.js +226 -0
- package/resolve-advanced/vendor/drx-codec/extract-power-window.js +184 -0
- package/resolve-advanced/vendor/drx-codec/extract-qualifier.js +99 -0
- package/resolve-advanced/vendor/drx-codec/index.js +109 -0
- package/resolve-advanced/vendor/drx-codec/node-layout.js +249 -0
- package/resolve-advanced/vendor/drx-codec/resolved-drx-generator.js +393 -0
- package/resolve-advanced/vendor/drx-codec/tool-resolver.js +974 -0
- package/resolve-advanced/vendor/drx-codec/training-examples.js +548 -0
- package/resolve-advanced/vendor/drx-codec/vocabulary-intents.js +539 -0
- package/resolve-advanced/vendor/drx-parameters/CALIBRATION-STATUS.md +319 -0
- package/resolve-advanced/vendor/drx-parameters/DRX-VALUE-SCALING.md +251 -0
- package/resolve-advanced/vendor/drx-parameters/calibrated-ranges.json +17737 -0
- package/resolve-advanced/vendor/drx-parameters/corrector-types.js +120 -0
- package/resolve-advanced/vendor/drx-parameters/index.js +193 -0
- package/resolve-advanced/vendor/drx-parameters/parameter-codec.js +451 -0
- package/resolve-advanced/vendor/drx-parameters/parameter-ids.js +1292 -0
- package/resolve-advanced/vendor/drx-parameters/parameter-ranges.js +570 -0
- package/resolve-advanced/vendor/drx-parameters/parameter-validator.js +392 -0
- package/resolve-advanced/vendor/drx-parameters/resolvefx-registry.json +14973 -0
- package/resolve-advanced/vendor/drx-parameters/tool-registry.descriptor.js +38 -0
- package/resolve-advanced/vendor/drx-parameters/tools/drx-analyzer.js +371 -0
- package/resolve-advanced/vendor/fairlight/index.js +833 -0
- package/resolve-advanced/vendor/fusion-codec/composition-generator.js +401 -0
- package/resolve-advanced/vendor/fusion-codec/templates/blur-region.js +103 -0
- package/resolve-advanced/vendor/fusion-codec/templates/color-correct.js +87 -0
- package/resolve-advanced/vendor/fusion-codec/templates/film-grain.js +106 -0
- package/resolve-advanced/vendor/fusion-codec/templates/lower-third.js +241 -0
- package/resolve-advanced/vendor/fusion-codec/templates/picture-in-picture.js +188 -0
- package/resolve-advanced/vendor/fusion-codec/templates/text-overlay.js +161 -0
- package/resolve-advanced/vendor/fusion-codec/templates/title-card.js +184 -0
- package/resolve-advanced/vendor/fusion-codec/templates/vignette.js +107 -0
- package/resolve-advanced/vendor/fusion-codec/templates/watermark.js +101 -0
- package/scripts/agent-rules/README.md +68 -0
- package/src/analysis_dashboard.py +233 -1
- package/src/granular/common.py +1 -1
- package/src/server.py +479 -29
- package/src/utils/api_truth.py +117 -0
- package/src/utils/cut_ir.py +1 -1
- package/src/utils/failure_tracker.py +0 -2
- package/src/utils/timeline_xml.py +405 -0
|
@@ -0,0 +1,774 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DaVinci Resolve Grade Parameter Decoder
|
|
3
|
+
*
|
|
4
|
+
* Comprehensive decoder for extracting color grading parameters from DRP Body data.
|
|
5
|
+
* Maps protobuf field IDs to actual color grading controls including:
|
|
6
|
+
* - Primary color wheels (Lift, Gamma, Gain, Offset)
|
|
7
|
+
* - Primary adjustments (Saturation, Hue, Contrast, Pivot, Luminance Mix)
|
|
8
|
+
* - Log wheels (Shadow, Midtone, Highlight)
|
|
9
|
+
* - Custom curves (RGB, Hue vs Sat, Lum vs Sat, etc.)
|
|
10
|
+
* - Qualifiers (HSL, 3D, Luminance)
|
|
11
|
+
* - Power Windows (Circle, Linear, Polygon, Curve, Gradient)
|
|
12
|
+
*
|
|
13
|
+
* Based on reverse-engineering of DaVinci Resolve 18/19 DRP protobuf format.
|
|
14
|
+
*
|
|
15
|
+
* @module grade-parameter-decoder
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const { parseGradeBody, parseProtobuf, initZstd } = require('./grade-node-extractor');
|
|
19
|
+
|
|
20
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
21
|
+
// FIELD ID MAPPINGS - Based on Resolve Protobuf Analysis
|
|
22
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Corrector Type IDs (Field 9.Field 1.Field 1)
|
|
26
|
+
*/
|
|
27
|
+
const CORRECTOR_TYPE = {
|
|
28
|
+
PRIMARY: 1, // Primary color wheels
|
|
29
|
+
CONTRAST: 2, // Contrast adjustment
|
|
30
|
+
SATURATION: 3, // Saturation adjustment
|
|
31
|
+
HUE: 4, // Hue rotation
|
|
32
|
+
LUM_MIX: 5, // Luminance mix
|
|
33
|
+
OFFSET: 6, // Offset wheels
|
|
34
|
+
LOG: 7, // Log wheels (Shadow/Mid/Highlight)
|
|
35
|
+
CURVES: 18, // Custom curves
|
|
36
|
+
QUALIFIER: 20, // HSL Qualifier
|
|
37
|
+
WINDOW: 25, // Power window
|
|
38
|
+
TRACKER: 26, // Tracking data
|
|
39
|
+
OFX: 30, // OFX plugin
|
|
40
|
+
LUT: 40, // LUT reference
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Primary Color Wheel Fields (inside corrector type 1)
|
|
45
|
+
*
|
|
46
|
+
* Each wheel has 4 floats: R, G, B, Master
|
|
47
|
+
* Neutral values are 1.0 for master, 0.0 for RGB offsets
|
|
48
|
+
*/
|
|
49
|
+
const PRIMARY_WHEELS = {
|
|
50
|
+
// Lift wheel - affects shadows
|
|
51
|
+
LIFT_R: { field: 1, subfield: 1, neutral: 0.0 },
|
|
52
|
+
LIFT_G: { field: 1, subfield: 2, neutral: 0.0 },
|
|
53
|
+
LIFT_B: { field: 1, subfield: 3, neutral: 0.0 },
|
|
54
|
+
LIFT_MASTER: { field: 1, subfield: 4, neutral: 1.0 },
|
|
55
|
+
|
|
56
|
+
// Gamma wheel - affects midtones
|
|
57
|
+
GAMMA_R: { field: 2, subfield: 1, neutral: 0.0 },
|
|
58
|
+
GAMMA_G: { field: 2, subfield: 2, neutral: 0.0 },
|
|
59
|
+
GAMMA_B: { field: 2, subfield: 3, neutral: 0.0 },
|
|
60
|
+
GAMMA_MASTER: { field: 2, subfield: 4, neutral: 1.0 },
|
|
61
|
+
|
|
62
|
+
// Gain wheel - affects highlights
|
|
63
|
+
GAIN_R: { field: 3, subfield: 1, neutral: 0.0 },
|
|
64
|
+
GAIN_G: { field: 3, subfield: 2, neutral: 0.0 },
|
|
65
|
+
GAIN_B: { field: 3, subfield: 3, neutral: 0.0 },
|
|
66
|
+
GAIN_MASTER: { field: 3, subfield: 4, neutral: 1.0 },
|
|
67
|
+
|
|
68
|
+
// Offset wheel - global offset
|
|
69
|
+
OFFSET_R: { field: 4, subfield: 1, neutral: 0.0 },
|
|
70
|
+
OFFSET_G: { field: 4, subfield: 2, neutral: 0.0 },
|
|
71
|
+
OFFSET_B: { field: 4, subfield: 3, neutral: 0.0 },
|
|
72
|
+
OFFSET_MASTER: { field: 4, subfield: 4, neutral: 0.0 },
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Primary Adjustment Fields
|
|
77
|
+
*/
|
|
78
|
+
const PRIMARY_ADJUSTMENTS = {
|
|
79
|
+
CONTRAST: { field: 5, neutral: 1.0, range: [0.0, 4.0] },
|
|
80
|
+
PIVOT: { field: 6, neutral: 0.435, range: [0.0, 1.0] },
|
|
81
|
+
SATURATION: { field: 7, neutral: 50.0, range: [0.0, 100.0] },
|
|
82
|
+
HUE: { field: 8, neutral: 50.0, range: [0.0, 100.0] },
|
|
83
|
+
LUM_MIX: { field: 9, neutral: 0.0, range: [0.0, 100.0] },
|
|
84
|
+
MIDTONE_DETAIL: { field: 10, neutral: 0.0, range: [-100.0, 100.0] },
|
|
85
|
+
COLOR_BOOST: { field: 11, neutral: 0.0, range: [0.0, 100.0] },
|
|
86
|
+
SHADOW_SAT: { field: 12, neutral: 50.0, range: [0.0, 100.0] },
|
|
87
|
+
HIGHLIGHT_SAT: { field: 13, neutral: 50.0, range: [0.0, 100.0] },
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Log Wheel Fields (inside corrector type 7)
|
|
92
|
+
*/
|
|
93
|
+
const LOG_WHEELS = {
|
|
94
|
+
// Shadow wheel
|
|
95
|
+
SHADOW_R: { field: 1, subfield: 1, neutral: 0.0 },
|
|
96
|
+
SHADOW_G: { field: 1, subfield: 2, neutral: 0.0 },
|
|
97
|
+
SHADOW_B: { field: 1, subfield: 3, neutral: 0.0 },
|
|
98
|
+
SHADOW_MASTER: { field: 1, subfield: 4, neutral: 0.0 },
|
|
99
|
+
|
|
100
|
+
// Midtone wheel
|
|
101
|
+
MIDTONE_R: { field: 2, subfield: 1, neutral: 0.0 },
|
|
102
|
+
MIDTONE_G: { field: 2, subfield: 2, neutral: 0.0 },
|
|
103
|
+
MIDTONE_B: { field: 2, subfield: 3, neutral: 0.0 },
|
|
104
|
+
MIDTONE_MASTER: { field: 2, subfield: 4, neutral: 0.0 },
|
|
105
|
+
|
|
106
|
+
// Highlight wheel
|
|
107
|
+
HIGHLIGHT_R: { field: 3, subfield: 1, neutral: 0.0 },
|
|
108
|
+
HIGHLIGHT_G: { field: 3, subfield: 2, neutral: 0.0 },
|
|
109
|
+
HIGHLIGHT_B: { field: 3, subfield: 3, neutral: 0.0 },
|
|
110
|
+
HIGHLIGHT_MASTER: { field: 3, subfield: 4, neutral: 0.0 },
|
|
111
|
+
|
|
112
|
+
// Log adjustments
|
|
113
|
+
LOW_RANGE: { field: 4, neutral: 0.0 },
|
|
114
|
+
HIGH_RANGE: { field: 5, neutral: 1.0 },
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Curve Types (inside corrector type 18)
|
|
119
|
+
*/
|
|
120
|
+
const CURVE_TYPES = {
|
|
121
|
+
CUSTOM: 1, // Luminance/overall curve
|
|
122
|
+
RED: 2, // Red channel curve
|
|
123
|
+
GREEN: 3, // Green channel curve
|
|
124
|
+
BLUE: 4, // Blue channel curve
|
|
125
|
+
HUE_VS_HUE: 5, // Hue vs Hue
|
|
126
|
+
HUE_VS_SAT: 6, // Hue vs Saturation
|
|
127
|
+
HUE_VS_LUM: 7, // Hue vs Luminance
|
|
128
|
+
LUM_VS_SAT: 8, // Luminance vs Saturation
|
|
129
|
+
SAT_VS_SAT: 9, // Saturation vs Saturation
|
|
130
|
+
SAT_VS_LUM: 10, // Saturation vs Luminance
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* HSL Qualifier Fields (inside corrector type 20)
|
|
135
|
+
*/
|
|
136
|
+
const HSL_QUALIFIER = {
|
|
137
|
+
ENABLED: { field: 1, neutral: false },
|
|
138
|
+
|
|
139
|
+
// Hue range
|
|
140
|
+
HUE_CENTER: { field: 2, neutral: 0.0, range: [0.0, 360.0] },
|
|
141
|
+
HUE_WIDTH: { field: 3, neutral: 30.0, range: [0.0, 180.0] },
|
|
142
|
+
HUE_SOFT: { field: 4, neutral: 0.0, range: [0.0, 100.0] },
|
|
143
|
+
|
|
144
|
+
// Saturation range
|
|
145
|
+
SAT_LOW: { field: 5, neutral: 0.0, range: [0.0, 100.0] },
|
|
146
|
+
SAT_HIGH: { field: 6, neutral: 100.0, range: [0.0, 100.0] },
|
|
147
|
+
SAT_LOW_SOFT: { field: 7, neutral: 0.0, range: [0.0, 100.0] },
|
|
148
|
+
SAT_HIGH_SOFT: { field: 8, neutral: 0.0, range: [0.0, 100.0] },
|
|
149
|
+
|
|
150
|
+
// Luminance range
|
|
151
|
+
LUM_LOW: { field: 9, neutral: 0.0, range: [0.0, 100.0] },
|
|
152
|
+
LUM_HIGH: { field: 10, neutral: 100.0, range: [0.0, 100.0] },
|
|
153
|
+
LUM_LOW_SOFT: { field: 11, neutral: 0.0, range: [0.0, 100.0] },
|
|
154
|
+
LUM_HIGH_SOFT: { field: 12, neutral: 0.0, range: [0.0, 100.0] },
|
|
155
|
+
|
|
156
|
+
// Matte options
|
|
157
|
+
INVERT: { field: 13, neutral: false },
|
|
158
|
+
MATTE_FINESSE: { field: 14, neutral: 0.0, range: [0.0, 100.0] },
|
|
159
|
+
DENOISE: { field: 15, neutral: 0.0, range: [0.0, 100.0] },
|
|
160
|
+
SHRINK_GROW: { field: 16, neutral: 0.0, range: [-100.0, 100.0] },
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Power Window Types (inside corrector type 25)
|
|
165
|
+
*/
|
|
166
|
+
const WINDOW_TYPES = {
|
|
167
|
+
CIRCLE: 1,
|
|
168
|
+
LINEAR: 2,
|
|
169
|
+
POLYGON: 3,
|
|
170
|
+
CURVE: 4,
|
|
171
|
+
GRADIENT: 5,
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Power Window Fields
|
|
176
|
+
*/
|
|
177
|
+
const WINDOW_FIELDS = {
|
|
178
|
+
TYPE: { field: 1 },
|
|
179
|
+
ENABLED: { field: 2, neutral: true },
|
|
180
|
+
|
|
181
|
+
// Transform
|
|
182
|
+
PAN_X: { field: 3, neutral: 0.0 },
|
|
183
|
+
PAN_Y: { field: 4, neutral: 0.0 },
|
|
184
|
+
ZOOM_X: { field: 5, neutral: 1.0 },
|
|
185
|
+
ZOOM_Y: { field: 6, neutral: 1.0 },
|
|
186
|
+
ROTATION: { field: 7, neutral: 0.0 },
|
|
187
|
+
ANCHOR_X: { field: 8, neutral: 0.5 },
|
|
188
|
+
ANCHOR_Y: { field: 9, neutral: 0.5 },
|
|
189
|
+
|
|
190
|
+
// Circle/Linear specific
|
|
191
|
+
RADIUS_X: { field: 10, neutral: 0.25 },
|
|
192
|
+
RADIUS_Y: { field: 11, neutral: 0.25 },
|
|
193
|
+
SOFTNESS: { field: 12, neutral: 0.0 },
|
|
194
|
+
INSIDE_SOFTNESS: { field: 13, neutral: 0.0 },
|
|
195
|
+
OUTSIDE_SOFTNESS: { field: 14, neutral: 0.0 },
|
|
196
|
+
|
|
197
|
+
// Linear specific
|
|
198
|
+
ANGLE: { field: 15, neutral: 0.0 },
|
|
199
|
+
POSITION: { field: 16, neutral: 0.5 },
|
|
200
|
+
|
|
201
|
+
// Polygon/Curve specific
|
|
202
|
+
POINTS: { field: 20 }, // Nested array of points
|
|
203
|
+
|
|
204
|
+
// Common
|
|
205
|
+
INVERT: { field: 30, neutral: false },
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
209
|
+
// DECODER FUNCTIONS
|
|
210
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Decode color wheels from corrector parameters
|
|
214
|
+
*
|
|
215
|
+
* @param {Array} fields - Parsed protobuf fields from corrector
|
|
216
|
+
* @param {Object} wheelDef - Wheel field definitions (PRIMARY_WHEELS or LOG_WHEELS)
|
|
217
|
+
* @returns {Object} Decoded wheel values
|
|
218
|
+
*/
|
|
219
|
+
function decodeColorWheels(fields, wheelDef) {
|
|
220
|
+
const wheels = {};
|
|
221
|
+
|
|
222
|
+
// Group fields by wheel number
|
|
223
|
+
const wheelFields = {};
|
|
224
|
+
for (const field of fields) {
|
|
225
|
+
if (!wheelFields[field.fieldNum]) {
|
|
226
|
+
wheelFields[field.fieldNum] = [];
|
|
227
|
+
}
|
|
228
|
+
wheelFields[field.fieldNum].push(field);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Extract each wheel's values
|
|
232
|
+
for (const [name, def] of Object.entries(wheelDef)) {
|
|
233
|
+
const wheelField = wheelFields[def.field];
|
|
234
|
+
if (wheelField && wheelField[0]?.nested) {
|
|
235
|
+
const subFields = wheelField[0].nested;
|
|
236
|
+
for (const sf of subFields) {
|
|
237
|
+
if (sf.fieldNum === def.subfield && (sf.type === 'float' || sf.type === 'double')) {
|
|
238
|
+
wheels[name] = sf.value;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Default to neutral if not found
|
|
244
|
+
if (wheels[name] === undefined) {
|
|
245
|
+
wheels[name] = def.neutral;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
return wheels;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Decode primary adjustments from corrector parameters
|
|
254
|
+
*
|
|
255
|
+
* @param {Array} fields - Parsed protobuf fields
|
|
256
|
+
* @returns {Object} Decoded adjustment values
|
|
257
|
+
*/
|
|
258
|
+
function decodePrimaryAdjustments(fields) {
|
|
259
|
+
const adjustments = {};
|
|
260
|
+
|
|
261
|
+
for (const [name, def] of Object.entries(PRIMARY_ADJUSTMENTS)) {
|
|
262
|
+
const field = fields.find((f) => f.fieldNum === def.field);
|
|
263
|
+
if (field && (field.type === 'float' || field.type === 'double')) {
|
|
264
|
+
adjustments[name] = field.value;
|
|
265
|
+
} else {
|
|
266
|
+
adjustments[name] = def.neutral;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
return adjustments;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Decode HSL qualifier settings
|
|
275
|
+
*
|
|
276
|
+
* @param {Array} fields - Parsed protobuf fields from qualifier corrector
|
|
277
|
+
* @returns {Object} Decoded qualifier settings
|
|
278
|
+
*/
|
|
279
|
+
function decodeHSLQualifier(fields) {
|
|
280
|
+
const qualifier = {};
|
|
281
|
+
|
|
282
|
+
for (const [name, def] of Object.entries(HSL_QUALIFIER)) {
|
|
283
|
+
const field = fields.find((f) => f.fieldNum === def.field);
|
|
284
|
+
|
|
285
|
+
if (field) {
|
|
286
|
+
if (def.neutral === false || def.neutral === true) {
|
|
287
|
+
qualifier[name] = field.value === 1;
|
|
288
|
+
} else if (field.type === 'float' || field.type === 'double') {
|
|
289
|
+
qualifier[name] = field.value;
|
|
290
|
+
} else if (field.type === 'varint') {
|
|
291
|
+
qualifier[name] = field.value;
|
|
292
|
+
}
|
|
293
|
+
} else {
|
|
294
|
+
qualifier[name] = def.neutral;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
return qualifier;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Decode power window settings
|
|
303
|
+
*
|
|
304
|
+
* @param {Array} fields - Parsed protobuf fields from window corrector
|
|
305
|
+
* @returns {Object} Decoded window settings
|
|
306
|
+
*/
|
|
307
|
+
function decodePowerWindow(fields) {
|
|
308
|
+
const window = {
|
|
309
|
+
type: 'unknown',
|
|
310
|
+
enabled: true,
|
|
311
|
+
transform: {},
|
|
312
|
+
shape: {},
|
|
313
|
+
invert: false,
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
for (const field of fields) {
|
|
317
|
+
switch (field.fieldNum) {
|
|
318
|
+
case WINDOW_FIELDS.TYPE.field:
|
|
319
|
+
window.type = Object.keys(WINDOW_TYPES).find(
|
|
320
|
+
(k) => WINDOW_TYPES[k] === field.value
|
|
321
|
+
) || 'unknown';
|
|
322
|
+
break;
|
|
323
|
+
case WINDOW_FIELDS.ENABLED.field:
|
|
324
|
+
window.enabled = field.value === 1;
|
|
325
|
+
break;
|
|
326
|
+
case WINDOW_FIELDS.PAN_X.field:
|
|
327
|
+
window.transform.panX = field.value;
|
|
328
|
+
break;
|
|
329
|
+
case WINDOW_FIELDS.PAN_Y.field:
|
|
330
|
+
window.transform.panY = field.value;
|
|
331
|
+
break;
|
|
332
|
+
case WINDOW_FIELDS.ZOOM_X.field:
|
|
333
|
+
window.transform.zoomX = field.value;
|
|
334
|
+
break;
|
|
335
|
+
case WINDOW_FIELDS.ZOOM_Y.field:
|
|
336
|
+
window.transform.zoomY = field.value;
|
|
337
|
+
break;
|
|
338
|
+
case WINDOW_FIELDS.ROTATION.field:
|
|
339
|
+
window.transform.rotation = field.value;
|
|
340
|
+
break;
|
|
341
|
+
case WINDOW_FIELDS.RADIUS_X.field:
|
|
342
|
+
window.shape.radiusX = field.value;
|
|
343
|
+
break;
|
|
344
|
+
case WINDOW_FIELDS.RADIUS_Y.field:
|
|
345
|
+
window.shape.radiusY = field.value;
|
|
346
|
+
break;
|
|
347
|
+
case WINDOW_FIELDS.SOFTNESS.field:
|
|
348
|
+
window.shape.softness = field.value;
|
|
349
|
+
break;
|
|
350
|
+
case WINDOW_FIELDS.INSIDE_SOFTNESS.field:
|
|
351
|
+
window.shape.insideSoftness = field.value;
|
|
352
|
+
break;
|
|
353
|
+
case WINDOW_FIELDS.OUTSIDE_SOFTNESS.field:
|
|
354
|
+
window.shape.outsideSoftness = field.value;
|
|
355
|
+
break;
|
|
356
|
+
case WINDOW_FIELDS.ANGLE.field:
|
|
357
|
+
window.shape.angle = field.value;
|
|
358
|
+
break;
|
|
359
|
+
case WINDOW_FIELDS.POSITION.field:
|
|
360
|
+
window.shape.position = field.value;
|
|
361
|
+
break;
|
|
362
|
+
case WINDOW_FIELDS.POINTS.field:
|
|
363
|
+
if (field.nested) {
|
|
364
|
+
window.shape.points = decodeWindowPoints(field.nested);
|
|
365
|
+
}
|
|
366
|
+
break;
|
|
367
|
+
case WINDOW_FIELDS.INVERT.field:
|
|
368
|
+
window.invert = field.value === 1;
|
|
369
|
+
break;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
return window;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Decode window polygon/curve points
|
|
378
|
+
*
|
|
379
|
+
* @param {Array} fields - Nested point data
|
|
380
|
+
* @returns {Array} Array of {x, y} points
|
|
381
|
+
*/
|
|
382
|
+
function decodeWindowPoints(fields) {
|
|
383
|
+
const points = [];
|
|
384
|
+
|
|
385
|
+
for (const field of fields) {
|
|
386
|
+
if (field.nested) {
|
|
387
|
+
const point = { x: 0, y: 0 };
|
|
388
|
+
for (const pf of field.nested) {
|
|
389
|
+
if (pf.fieldNum === 1) point.x = pf.value;
|
|
390
|
+
if (pf.fieldNum === 2) point.y = pf.value;
|
|
391
|
+
}
|
|
392
|
+
points.push(point);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
return points;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Decode curve control points
|
|
401
|
+
*
|
|
402
|
+
* @param {Array} fields - Curve data fields
|
|
403
|
+
* @returns {Object} Curve definition with type and points
|
|
404
|
+
*/
|
|
405
|
+
function decodeCurve(fields) {
|
|
406
|
+
const curve = {
|
|
407
|
+
type: 'CUSTOM',
|
|
408
|
+
enabled: true,
|
|
409
|
+
points: [],
|
|
410
|
+
interpolation: 'bezier',
|
|
411
|
+
};
|
|
412
|
+
|
|
413
|
+
for (const field of fields) {
|
|
414
|
+
switch (field.fieldNum) {
|
|
415
|
+
case 1:
|
|
416
|
+
curve.type = Object.keys(CURVE_TYPES).find(
|
|
417
|
+
(k) => CURVE_TYPES[k] === field.value
|
|
418
|
+
) || 'CUSTOM';
|
|
419
|
+
break;
|
|
420
|
+
case 2:
|
|
421
|
+
curve.enabled = field.value === 1;
|
|
422
|
+
break;
|
|
423
|
+
case 3:
|
|
424
|
+
if (field.nested) {
|
|
425
|
+
curve.points = decodeCurvePoints(field.nested);
|
|
426
|
+
}
|
|
427
|
+
break;
|
|
428
|
+
case 4:
|
|
429
|
+
curve.interpolation = field.value === 1 ? 'linear' : 'bezier';
|
|
430
|
+
break;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
return curve;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Decode curve control points with handles
|
|
439
|
+
*
|
|
440
|
+
* @param {Array} fields - Point data
|
|
441
|
+
* @returns {Array} Array of curve points with handles
|
|
442
|
+
*/
|
|
443
|
+
function decodeCurvePoints(fields) {
|
|
444
|
+
const points = [];
|
|
445
|
+
|
|
446
|
+
for (const field of fields) {
|
|
447
|
+
if (field.nested) {
|
|
448
|
+
const point = {
|
|
449
|
+
x: 0,
|
|
450
|
+
y: 0,
|
|
451
|
+
handleInX: 0,
|
|
452
|
+
handleInY: 0,
|
|
453
|
+
handleOutX: 0,
|
|
454
|
+
handleOutY: 0,
|
|
455
|
+
};
|
|
456
|
+
|
|
457
|
+
for (const pf of field.nested) {
|
|
458
|
+
switch (pf.fieldNum) {
|
|
459
|
+
case 1: point.x = pf.value; break;
|
|
460
|
+
case 2: point.y = pf.value; break;
|
|
461
|
+
case 3: point.handleInX = pf.value; break;
|
|
462
|
+
case 4: point.handleInY = pf.value; break;
|
|
463
|
+
case 5: point.handleOutX = pf.value; break;
|
|
464
|
+
case 6: point.handleOutY = pf.value; break;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
points.push(point);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
return points;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Decode a complete color corrector node
|
|
477
|
+
*
|
|
478
|
+
* @param {Object} corrector - Corrector data from grade-node-extractor
|
|
479
|
+
* @returns {Object} Fully decoded corrector with all parameters
|
|
480
|
+
*/
|
|
481
|
+
function decodeCorrector(corrector) {
|
|
482
|
+
const decoded = {
|
|
483
|
+
type: corrector.type,
|
|
484
|
+
typeId: corrector.typeId,
|
|
485
|
+
enabled: corrector.enabled,
|
|
486
|
+
values: {},
|
|
487
|
+
};
|
|
488
|
+
|
|
489
|
+
switch (corrector.typeId) {
|
|
490
|
+
case CORRECTOR_TYPE.PRIMARY:
|
|
491
|
+
decoded.values.wheels = decodeColorWheels(corrector.values || [], PRIMARY_WHEELS);
|
|
492
|
+
break;
|
|
493
|
+
|
|
494
|
+
case CORRECTOR_TYPE.LOG:
|
|
495
|
+
decoded.values.wheels = decodeColorWheels(corrector.values || [], LOG_WHEELS);
|
|
496
|
+
break;
|
|
497
|
+
|
|
498
|
+
case CORRECTOR_TYPE.CONTRAST:
|
|
499
|
+
case CORRECTOR_TYPE.SATURATION:
|
|
500
|
+
case CORRECTOR_TYPE.HUE:
|
|
501
|
+
case CORRECTOR_TYPE.LUM_MIX:
|
|
502
|
+
case CORRECTOR_TYPE.OFFSET:
|
|
503
|
+
decoded.values = decodePrimaryAdjustments(corrector.values || []);
|
|
504
|
+
break;
|
|
505
|
+
|
|
506
|
+
case CORRECTOR_TYPE.CURVES:
|
|
507
|
+
decoded.values.curves = [];
|
|
508
|
+
for (const field of corrector.values || []) {
|
|
509
|
+
if (field.nested) {
|
|
510
|
+
decoded.values.curves.push(decodeCurve(field.nested));
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
break;
|
|
514
|
+
|
|
515
|
+
case CORRECTOR_TYPE.QUALIFIER:
|
|
516
|
+
decoded.values.qualifier = decodeHSLQualifier(corrector.values || []);
|
|
517
|
+
break;
|
|
518
|
+
|
|
519
|
+
case CORRECTOR_TYPE.WINDOW:
|
|
520
|
+
decoded.values.window = decodePowerWindow(corrector.values || []);
|
|
521
|
+
break;
|
|
522
|
+
|
|
523
|
+
case CORRECTOR_TYPE.LUT:
|
|
524
|
+
decoded.values.lut = decodeLUTReference(corrector.values || []);
|
|
525
|
+
break;
|
|
526
|
+
|
|
527
|
+
default:
|
|
528
|
+
// Keep raw values for unknown types
|
|
529
|
+
decoded.values.raw = corrector.values;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
return decoded;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
/**
|
|
536
|
+
* Decode LUT reference
|
|
537
|
+
*
|
|
538
|
+
* @param {Array} fields - LUT corrector fields
|
|
539
|
+
* @returns {Object} LUT reference with path and strength
|
|
540
|
+
*/
|
|
541
|
+
function decodeLUTReference(fields) {
|
|
542
|
+
const lut = {
|
|
543
|
+
path: null,
|
|
544
|
+
strength: 1.0,
|
|
545
|
+
inputColorSpace: null,
|
|
546
|
+
outputColorSpace: null,
|
|
547
|
+
};
|
|
548
|
+
|
|
549
|
+
for (const field of fields) {
|
|
550
|
+
switch (field.fieldNum) {
|
|
551
|
+
case 1:
|
|
552
|
+
if (field.raw) {
|
|
553
|
+
lut.path = field.raw.toString('utf-8').replace(/\x00/g, '');
|
|
554
|
+
}
|
|
555
|
+
break;
|
|
556
|
+
case 2:
|
|
557
|
+
lut.strength = field.value;
|
|
558
|
+
break;
|
|
559
|
+
case 3:
|
|
560
|
+
if (field.raw) {
|
|
561
|
+
lut.inputColorSpace = field.raw.toString('utf-8').replace(/\x00/g, '');
|
|
562
|
+
}
|
|
563
|
+
break;
|
|
564
|
+
case 4:
|
|
565
|
+
if (field.raw) {
|
|
566
|
+
lut.outputColorSpace = field.raw.toString('utf-8').replace(/\x00/g, '');
|
|
567
|
+
}
|
|
568
|
+
break;
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
return lut;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
/**
|
|
576
|
+
* Decode all parameters from a grade body
|
|
577
|
+
*
|
|
578
|
+
* @param {string} hexData - Hex-encoded Body data from DRP
|
|
579
|
+
* @returns {Promise<Object>} Complete decoded grade data
|
|
580
|
+
*/
|
|
581
|
+
async function decodeGradeParameters(hexData) {
|
|
582
|
+
const gradeData = await parseGradeBody(hexData);
|
|
583
|
+
|
|
584
|
+
const decoded = {
|
|
585
|
+
nodes: [],
|
|
586
|
+
connections: gradeData.connections || [],
|
|
587
|
+
metadata: {
|
|
588
|
+
nodeCount: gradeData.nodes?.length || 0,
|
|
589
|
+
hasCorrections: false,
|
|
590
|
+
},
|
|
591
|
+
};
|
|
592
|
+
|
|
593
|
+
for (const node of gradeData.nodes || []) {
|
|
594
|
+
const decodedNode = {
|
|
595
|
+
id: node.id,
|
|
596
|
+
index: node.index,
|
|
597
|
+
label: node.label,
|
|
598
|
+
posX: node.posX,
|
|
599
|
+
posY: node.posY,
|
|
600
|
+
enabled: node.enabled,
|
|
601
|
+
timestamp: node.timestamp,
|
|
602
|
+
correctors: [],
|
|
603
|
+
};
|
|
604
|
+
|
|
605
|
+
for (const param of node.parameters || []) {
|
|
606
|
+
const decodedCorrector = decodeCorrector(param);
|
|
607
|
+
decodedNode.correctors.push(decodedCorrector);
|
|
608
|
+
|
|
609
|
+
// Check if any correction is non-neutral
|
|
610
|
+
if (decodedCorrector.enabled && hasNonNeutralValues(decodedCorrector)) {
|
|
611
|
+
decoded.metadata.hasCorrections = true;
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
decoded.nodes.push(decodedNode);
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
return decoded;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
/**
|
|
622
|
+
* Check if a corrector has non-neutral values
|
|
623
|
+
*
|
|
624
|
+
* @param {Object} corrector - Decoded corrector
|
|
625
|
+
* @returns {boolean} True if corrector has adjustments
|
|
626
|
+
*/
|
|
627
|
+
function hasNonNeutralValues(corrector) {
|
|
628
|
+
const values = corrector.values;
|
|
629
|
+
|
|
630
|
+
// Check wheels
|
|
631
|
+
if (values.wheels) {
|
|
632
|
+
for (const [key, value] of Object.entries(values.wheels)) {
|
|
633
|
+
const def = PRIMARY_WHEELS[key] || LOG_WHEELS[key];
|
|
634
|
+
if (def && Math.abs(value - def.neutral) > 0.001) {
|
|
635
|
+
return true;
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
// Check adjustments
|
|
641
|
+
for (const [key, def] of Object.entries(PRIMARY_ADJUSTMENTS)) {
|
|
642
|
+
if (values[key] !== undefined && Math.abs(values[key] - def.neutral) > 0.001) {
|
|
643
|
+
return true;
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
// Check curves
|
|
648
|
+
if (values.curves?.length > 0) {
|
|
649
|
+
for (const curve of values.curves) {
|
|
650
|
+
if (curve.points?.length > 2) return true;
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
// Check qualifier
|
|
655
|
+
if (values.qualifier?.ENABLED) {
|
|
656
|
+
return true;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
// Check window
|
|
660
|
+
if (values.window?.enabled) {
|
|
661
|
+
return true;
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
// Check LUT
|
|
665
|
+
if (values.lut?.path) {
|
|
666
|
+
return true;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
return false;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
/**
|
|
673
|
+
* Format decoded parameters for display
|
|
674
|
+
*
|
|
675
|
+
* @param {Object} decoded - Decoded grade data
|
|
676
|
+
* @returns {string} Human-readable format
|
|
677
|
+
*/
|
|
678
|
+
function formatDecodedGrade(decoded) {
|
|
679
|
+
const lines = [];
|
|
680
|
+
|
|
681
|
+
lines.push(`Grade Data (${decoded.nodes.length} nodes)`);
|
|
682
|
+
lines.push(`Has Corrections: ${decoded.metadata.hasCorrections}`);
|
|
683
|
+
lines.push('');
|
|
684
|
+
|
|
685
|
+
for (const node of decoded.nodes) {
|
|
686
|
+
lines.push(`═══ Node ${node.id} (${node.label || 'Unlabeled'}) ═══`);
|
|
687
|
+
lines.push(` Enabled: ${node.enabled}`);
|
|
688
|
+
lines.push(` Position: (${node.posX}, ${node.posY})`);
|
|
689
|
+
|
|
690
|
+
for (const corrector of node.correctors) {
|
|
691
|
+
lines.push(` ─── ${corrector.type} (${corrector.enabled ? 'ON' : 'OFF'}) ───`);
|
|
692
|
+
|
|
693
|
+
if (corrector.values.wheels) {
|
|
694
|
+
lines.push(' Wheels:');
|
|
695
|
+
for (const [name, value] of Object.entries(corrector.values.wheels)) {
|
|
696
|
+
if (typeof value === 'number' && Math.abs(value) > 0.001) {
|
|
697
|
+
lines.push(` ${name}: ${value.toFixed(4)}`);
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
if (corrector.values.qualifier) {
|
|
703
|
+
lines.push(' HSL Qualifier:');
|
|
704
|
+
const q = corrector.values.qualifier;
|
|
705
|
+
lines.push(` Hue: ${q.HUE_CENTER}° ± ${q.HUE_WIDTH}°`);
|
|
706
|
+
lines.push(` Sat: ${q.SAT_LOW}-${q.SAT_HIGH}`);
|
|
707
|
+
lines.push(` Lum: ${q.LUM_LOW}-${q.LUM_HIGH}`);
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
if (corrector.values.window) {
|
|
711
|
+
const w = corrector.values.window;
|
|
712
|
+
lines.push(` Window: ${w.type}`);
|
|
713
|
+
lines.push(` Pan: (${w.transform.panX?.toFixed(3)}, ${w.transform.panY?.toFixed(3)})`);
|
|
714
|
+
lines.push(` Zoom: (${w.transform.zoomX?.toFixed(3)}, ${w.transform.zoomY?.toFixed(3)})`);
|
|
715
|
+
lines.push(` Rotation: ${w.transform.rotation?.toFixed(1)}°`);
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
if (corrector.values.curves?.length > 0) {
|
|
719
|
+
lines.push(` Curves: ${corrector.values.curves.length}`);
|
|
720
|
+
for (const curve of corrector.values.curves) {
|
|
721
|
+
lines.push(` ${curve.type}: ${curve.points.length} points`);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
if (corrector.values.lut?.path) {
|
|
726
|
+
lines.push(` LUT: ${corrector.values.lut.path}`);
|
|
727
|
+
lines.push(` Strength: ${corrector.values.lut.strength}`);
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
lines.push('');
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
if (decoded.connections.length > 0) {
|
|
735
|
+
lines.push('Connections:');
|
|
736
|
+
for (const conn of decoded.connections) {
|
|
737
|
+
lines.push(` Node ${conn.sourceNode} → Node ${conn.targetNode}`);
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
return lines.join('\n');
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
745
|
+
// EXPORTS
|
|
746
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
747
|
+
|
|
748
|
+
module.exports = {
|
|
749
|
+
// Main decoder
|
|
750
|
+
decodeGradeParameters,
|
|
751
|
+
|
|
752
|
+
// Sub-decoders
|
|
753
|
+
decodeColorWheels,
|
|
754
|
+
decodePrimaryAdjustments,
|
|
755
|
+
decodeHSLQualifier,
|
|
756
|
+
decodePowerWindow,
|
|
757
|
+
decodeCurve,
|
|
758
|
+
decodeLUTReference,
|
|
759
|
+
decodeCorrector,
|
|
760
|
+
|
|
761
|
+
// Utilities
|
|
762
|
+
hasNonNeutralValues,
|
|
763
|
+
formatDecodedGrade,
|
|
764
|
+
|
|
765
|
+
// Constants
|
|
766
|
+
CORRECTOR_TYPE,
|
|
767
|
+
PRIMARY_WHEELS,
|
|
768
|
+
PRIMARY_ADJUSTMENTS,
|
|
769
|
+
LOG_WHEELS,
|
|
770
|
+
CURVE_TYPES,
|
|
771
|
+
HSL_QUALIFIER,
|
|
772
|
+
WINDOW_TYPES,
|
|
773
|
+
WINDOW_FIELDS,
|
|
774
|
+
};
|