Live video on the AT Protocol

c2pa: add working c2patypes class

+1402 -3079
-1345
pkg/c2pa/Builder.schema.json
··· 1 - { 2 - "$schema": "http://json-schema.org/draft-07/schema#", 3 - "title": "Builder", 4 - "description": "Use a Builder to add a signed manifest to an asset.\n\n# Example: Building and signing a manifest\n\n``` use c2pa::Result; use std::path::PathBuf;\n\nuse c2pa::{create_signer, Builder, SigningAlg}; use serde::Serialize; use serde_json::json; use tempfile::tempdir;\n\n#[derive(Serialize)] struct Test { my_tag: usize, }\n\n# fn main() -> Result<()> { #[cfg(feature = \"file_io\")] { let manifest_json = json!({ \"claim_generator_info\": [ { \"name\": \"c2pa_test\", \"version\": \"1.0.0\" } ], \"title\": \"Test_Manifest\" }).to_string();\n\nlet mut builder = Builder::from_json(&manifest_json)?; builder.add_assertion(\"org.contentauth.test\", &Test { my_tag: 42 })?;\n\nlet source = PathBuf::from(\"tests/fixtures/C.jpg\"); let dir = tempdir()?; let dest = dir.path().join(\"test_file.jpg\");\n\n// Create a ps256 signer using certs and key files. TO DO: Update example. let signcert_path = \"tests/fixtures/certs/ps256.pub\"; let pkey_path = \"tests/fixtures/certs/ps256.pem\"; let signer = create_signer::from_files(signcert_path, pkey_path, SigningAlg::Ps256, None)?;\n\n// embed a manifest using the signer builder.sign_file( signer.as_ref(), &source, &dest)?; } # Ok(()) # } ```", 5 - "type": "object", 6 - "required": [ 7 - "no_embed" 8 - ], 9 - "properties": { 10 - "assertions": { 11 - "description": "A list of assertions", 12 - "default": [], 13 - "type": "array", 14 - "items": { 15 - "$ref": "#/definitions/AssertionDefinition" 16 - } 17 - }, 18 - "base_path": { 19 - "description": "Base path to search for resources.", 20 - "type": [ 21 - "string", 22 - "null" 23 - ] 24 - }, 25 - "builder_flow": { 26 - "description": "The type of builder being used.", 27 - "anyOf": [ 28 - { 29 - "$ref": "#/definitions/BuilderFlow" 30 - }, 31 - { 32 - "type": "null" 33 - } 34 - ] 35 - }, 36 - "claim_generator_info": { 37 - "description": "Claim Generator Info is always required with at least one entry", 38 - "default": [ 39 - { 40 - "name": "c2pa-rs", 41 - "version": "0.58.0" 42 - } 43 - ], 44 - "type": "array", 45 - "items": { 46 - "$ref": "#/definitions/ClaimGeneratorInfo" 47 - } 48 - }, 49 - "claim_version": { 50 - "description": "The version of the claim. Defaults to 1.", 51 - "type": [ 52 - "integer", 53 - "null" 54 - ], 55 - "format": "uint8", 56 - "minimum": 0.0 57 - }, 58 - "format": { 59 - "description": "The format of the source file as a MIME type.", 60 - "default": "application/octet-stream", 61 - "type": "string" 62 - }, 63 - "ingredients": { 64 - "description": "A List of ingredients", 65 - "default": [], 66 - "type": "array", 67 - "items": { 68 - "$ref": "#/definitions/Ingredient" 69 - } 70 - }, 71 - "instance_id": { 72 - "description": "Instance ID from `xmpMM:InstanceID` in XMP metadata.", 73 - "default": "xmp:iid:4caa88cb-6034-4d42-8969-409379d34945", 74 - "type": "string" 75 - }, 76 - "label": { 77 - "description": "Allows you to pre-define the manifest label, which must be unique. Not intended for general use. If not set, it will be assigned automatically.", 78 - "type": [ 79 - "string", 80 - "null" 81 - ] 82 - }, 83 - "metadata": { 84 - "description": "Optional manifest metadata. This will be deprecated in the future; not recommended to use.", 85 - "type": [ 86 - "array", 87 - "null" 88 - ], 89 - "items": { 90 - "$ref": "#/definitions/AssertionMetadata" 91 - } 92 - }, 93 - "no_embed": { 94 - "description": "If true, the manifest store will not be embedded in the asset on sign", 95 - "type": "boolean" 96 - }, 97 - "redactions": { 98 - "description": "A list of redactions - URIs to redacted assertions.", 99 - "type": [ 100 - "array", 101 - "null" 102 - ], 103 - "items": { 104 - "type": "string" 105 - } 106 - }, 107 - "remote_url": { 108 - "description": "Optional remote URL for the manifest", 109 - "type": [ 110 - "string", 111 - "null" 112 - ] 113 - }, 114 - "thumbnail": { 115 - "description": "An optional ResourceRef to a thumbnail image that represents the asset that was signed. Must be available when the manifest is signed.", 116 - "anyOf": [ 117 - { 118 - "$ref": "#/definitions/ResourceRef" 119 - }, 120 - { 121 - "type": "null" 122 - } 123 - ] 124 - }, 125 - "title": { 126 - "description": "A human-readable title, generally source filename.", 127 - "type": [ 128 - "string", 129 - "null" 130 - ] 131 - }, 132 - "vendor": { 133 - "description": "Optional prefix added to the generated Manifest Label This is typically a reverse domain name.", 134 - "type": [ 135 - "string", 136 - "null" 137 - ] 138 - } 139 - }, 140 - "definitions": { 141 - "Actor": { 142 - "description": "Identifies a person responsible for an action.", 143 - "type": "object", 144 - "properties": { 145 - "credentials": { 146 - "description": "List of references to W3C Verifiable Credentials.", 147 - "type": [ 148 - "array", 149 - "null" 150 - ], 151 - "items": { 152 - "$ref": "#/definitions/HashedUri" 153 - } 154 - }, 155 - "identifier": { 156 - "description": "An identifier for a human actor, used when the \"type\" is `humanEntry.identified`.", 157 - "type": [ 158 - "string", 159 - "null" 160 - ] 161 - } 162 - } 163 - }, 164 - "AssertionData": { 165 - "description": "This allows the assertion to be expressed as CBOR or JSON. The default is CBOR unless you specify that an assertion should be JSON.", 166 - "anyOf": [ 167 - true 168 - ] 169 - }, 170 - "AssertionDefinition": { 171 - "description": "Defines an assertion that consists of a label that can be either a C2PA-defined assertion label or a custom label in reverse domain format.", 172 - "type": "object", 173 - "required": [ 174 - "data", 175 - "label" 176 - ], 177 - "properties": { 178 - "data": { 179 - "$ref": "#/definitions/AssertionData" 180 - }, 181 - "label": { 182 - "type": "string" 183 - } 184 - } 185 - }, 186 - "AssertionMetadata": { 187 - "description": "The AssertionMetadata structure can be used as part of other assertions or on its own to reference others", 188 - "type": "object", 189 - "properties": { 190 - "dataSource": { 191 - "anyOf": [ 192 - { 193 - "$ref": "#/definitions/DataSource" 194 - }, 195 - { 196 - "type": "null" 197 - } 198 - ] 199 - }, 200 - "dateTime": { 201 - "anyOf": [ 202 - { 203 - "$ref": "#/definitions/DateT" 204 - }, 205 - { 206 - "type": "null" 207 - } 208 - ] 209 - }, 210 - "reference": { 211 - "anyOf": [ 212 - { 213 - "$ref": "#/definitions/HashedUri" 214 - }, 215 - { 216 - "type": "null" 217 - } 218 - ] 219 - }, 220 - "regionOfInterest": { 221 - "anyOf": [ 222 - { 223 - "$ref": "#/definitions/RegionOfInterest" 224 - }, 225 - { 226 - "type": "null" 227 - } 228 - ] 229 - }, 230 - "reviewRatings": { 231 - "type": [ 232 - "array", 233 - "null" 234 - ], 235 - "items": { 236 - "$ref": "#/definitions/ReviewRating" 237 - } 238 - } 239 - } 240 - }, 241 - "AssetType": { 242 - "type": "object", 243 - "required": [ 244 - "type" 245 - ], 246 - "properties": { 247 - "type": { 248 - "type": "string" 249 - }, 250 - "version": { 251 - "type": [ 252 - "string", 253 - "null" 254 - ] 255 - } 256 - } 257 - }, 258 - "BuilderFlow": { 259 - "description": "Represents the type of builder flow being used.\n\nThis determines how the builder will be used, such as creating a new asset, opening an existing asset, or updating an existing asset.", 260 - "oneOf": [ 261 - { 262 - "type": "string", 263 - "enum": [ 264 - "Open", 265 - "Update" 266 - ] 267 - }, 268 - { 269 - "type": "object", 270 - "required": [ 271 - "Create" 272 - ], 273 - "properties": { 274 - "Create": { 275 - "$ref": "#/definitions/DigitalSourceType" 276 - } 277 - }, 278 - "additionalProperties": false 279 - } 280 - ] 281 - }, 282 - "ClaimGeneratorInfo": { 283 - "description": "Description of the claim generator, or the software used in generating the claim.\n\nThis structure is also used for actions softwareAgent", 284 - "type": "object", 285 - "required": [ 286 - "name" 287 - ], 288 - "properties": { 289 - "icon": { 290 - "description": "hashed URI to the icon (either embedded or remote)", 291 - "anyOf": [ 292 - { 293 - "$ref": "#/definitions/UriOrResource" 294 - }, 295 - { 296 - "type": "null" 297 - } 298 - ] 299 - }, 300 - "name": { 301 - "description": "A human readable string naming the claim_generator", 302 - "type": "string" 303 - }, 304 - "operating_system": { 305 - "description": "A human readable string of the OS the claim generator is running on", 306 - "type": [ 307 - "string", 308 - "null" 309 - ] 310 - }, 311 - "version": { 312 - "description": "A human readable string of the product's version", 313 - "type": [ 314 - "string", 315 - "null" 316 - ] 317 - } 318 - }, 319 - "additionalProperties": true 320 - }, 321 - "Coordinate": { 322 - "description": "An x, y coordinate used for specifying vertices in polygons.", 323 - "type": "object", 324 - "required": [ 325 - "x", 326 - "y" 327 - ], 328 - "properties": { 329 - "x": { 330 - "description": "The coordinate along the x-axis.", 331 - "type": "number", 332 - "format": "double" 333 - }, 334 - "y": { 335 - "description": "The coordinate along the y-axis.", 336 - "type": "number", 337 - "format": "double" 338 - } 339 - } 340 - }, 341 - "DataSource": { 342 - "description": "A description of the source for assertion data", 343 - "type": "object", 344 - "required": [ 345 - "type" 346 - ], 347 - "properties": { 348 - "actors": { 349 - "description": "A list of [`Actor`]s associated with this source.", 350 - "type": [ 351 - "array", 352 - "null" 353 - ], 354 - "items": { 355 - "$ref": "#/definitions/Actor" 356 - } 357 - }, 358 - "details": { 359 - "description": "A human-readable string giving details about the source of the assertion data.", 360 - "type": [ 361 - "string", 362 - "null" 363 - ] 364 - }, 365 - "type": { 366 - "description": "A value from among the enumerated list indicating the source of the assertion.", 367 - "type": "string" 368 - } 369 - } 370 - }, 371 - "DateT": { 372 - "type": "string" 373 - }, 374 - "DigitalSourceType": { 375 - "oneOf": [ 376 - { 377 - "description": "Media whose digital content is effectively empty, such as a blank canvas or zero-length video.", 378 - "type": "string", 379 - "enum": [ 380 - "Empty" 381 - ] 382 - }, 383 - { 384 - "description": "Data that is the result of algorithmically using a model derived from sampled content and data. Differs from <http://cv.iptc.org/newscodes/digitalsourcetype/>trainedAlgorithmicMedia in that the result isn’t a media type (e.g., image or video) but is a data format (e.g., CSV, pickle).", 385 - "type": "string", 386 - "enum": [ 387 - "TrainedAlgorithmicData" 388 - ] 389 - } 390 - ] 391 - }, 392 - "Frame": { 393 - "description": "A frame range representing starting and ending frames or pages.\n\nIf both `start` and `end` are missing, the frame will span the entire asset.", 394 - "type": "object", 395 - "properties": { 396 - "end": { 397 - "description": "The end of the frame inclusive or the end of the asset if not present.", 398 - "type": [ 399 - "integer", 400 - "null" 401 - ], 402 - "format": "int32" 403 - }, 404 - "start": { 405 - "description": "The start of the frame or the end of the asset if not present.\n\nThe first frame/page starts at 0.", 406 - "type": [ 407 - "integer", 408 - "null" 409 - ], 410 - "format": "int32" 411 - } 412 - } 413 - }, 414 - "HashedUri": { 415 - "description": "A `HashedUri` provides a reference to content available within the same manifest store.\n\nThis is described in [§8.3, URI References], of the C2PA Technical Specification.\n\n[§8.3, URI References]: https://c2pa.org/specifications/specifications/2.1/specs/C2PA_Specification.html#_uri_references", 416 - "type": "object", 417 - "required": [ 418 - "hash", 419 - "url" 420 - ], 421 - "properties": { 422 - "alg": { 423 - "description": "A string identifying the cryptographic hash algorithm used to compute the hash", 424 - "type": [ 425 - "string", 426 - "null" 427 - ] 428 - }, 429 - "hash": { 430 - "description": "Byte string containing the hash value", 431 - "type": "array", 432 - "items": { 433 - "type": "integer", 434 - "format": "uint8", 435 - "minimum": 0.0 436 - } 437 - }, 438 - "url": { 439 - "description": "JUMBF URI reference", 440 - "type": "string" 441 - } 442 - } 443 - }, 444 - "Ingredient": { 445 - "description": "An `Ingredient` is any external asset that has been used in the creation of an asset.", 446 - "type": "object", 447 - "properties": { 448 - "active_manifest": { 449 - "description": "The active manifest label (if one exists).\n\nIf this ingredient has a [`ManifestStore`], this will hold the label of the active [`Manifest`].\n\n[`Manifest`]: crate::Manifest [`ManifestStore`]: crate::ManifestStore", 450 - "type": [ 451 - "string", 452 - "null" 453 - ] 454 - }, 455 - "data": { 456 - "description": "A reference to the actual data of the ingredient.", 457 - "anyOf": [ 458 - { 459 - "$ref": "#/definitions/ResourceRef" 460 - }, 461 - { 462 - "type": "null" 463 - } 464 - ] 465 - }, 466 - "data_types": { 467 - "description": "Additional information about the data's type to the ingredient V2 structure.", 468 - "type": [ 469 - "array", 470 - "null" 471 - ], 472 - "items": { 473 - "$ref": "#/definitions/AssetType" 474 - } 475 - }, 476 - "description": { 477 - "description": "Additional description of the ingredient.", 478 - "type": [ 479 - "string", 480 - "null" 481 - ] 482 - }, 483 - "document_id": { 484 - "description": "Document ID from `xmpMM:DocumentID` in XMP metadata.", 485 - "type": [ 486 - "string", 487 - "null" 488 - ] 489 - }, 490 - "format": { 491 - "description": "The format of the source file as a MIME type.", 492 - "type": [ 493 - "string", 494 - "null" 495 - ] 496 - }, 497 - "hash": { 498 - "description": "An optional hash of the asset to prevent duplicates.", 499 - "type": [ 500 - "string", 501 - "null" 502 - ] 503 - }, 504 - "informational_URI": { 505 - "description": "URI to an informational page about the ingredient or its data.", 506 - "type": [ 507 - "string", 508 - "null" 509 - ] 510 - }, 511 - "instance_id": { 512 - "description": "Instance ID from `xmpMM:InstanceID` in XMP metadata.", 513 - "type": [ 514 - "string", 515 - "null" 516 - ] 517 - }, 518 - "label": { 519 - "description": "The ingredient's label as assigned in the manifest.", 520 - "type": [ 521 - "string", 522 - "null" 523 - ] 524 - }, 525 - "manifest_data": { 526 - "description": "A [`ManifestStore`] from the source asset extracted as a binary C2PA blob.\n\n[`ManifestStore`]: crate::ManifestStore", 527 - "anyOf": [ 528 - { 529 - "$ref": "#/definitions/ResourceRef" 530 - }, 531 - { 532 - "type": "null" 533 - } 534 - ] 535 - }, 536 - "metadata": { 537 - "description": "Any additional [`Metadata`] as defined in the C2PA spec.\n\n[`Metadata`]: crate::Metadata", 538 - "anyOf": [ 539 - { 540 - "$ref": "#/definitions/AssertionMetadata" 541 - }, 542 - { 543 - "type": "null" 544 - } 545 - ] 546 - }, 547 - "provenance": { 548 - "description": "URI from `dcterms:provenance` in XMP metadata.", 549 - "type": [ 550 - "string", 551 - "null" 552 - ] 553 - }, 554 - "relationship": { 555 - "description": "Set to `ParentOf` if this is the parent ingredient.\n\nThere can only be one parent ingredient in the ingredients.", 556 - "default": "componentOf", 557 - "allOf": [ 558 - { 559 - "$ref": "#/definitions/Relationship" 560 - } 561 - ] 562 - }, 563 - "resources": { 564 - "readOnly": true, 565 - "allOf": [ 566 - { 567 - "$ref": "#/definitions/ResourceStore" 568 - } 569 - ] 570 - }, 571 - "thumbnail": { 572 - "description": "A thumbnail image capturing the visual state at the time of import.\n\nA tuple of thumbnail MIME format (for example `image/jpeg`) and binary bits of the image.", 573 - "anyOf": [ 574 - { 575 - "$ref": "#/definitions/ResourceRef" 576 - }, 577 - { 578 - "type": "null" 579 - } 580 - ] 581 - }, 582 - "title": { 583 - "description": "A human-readable title, generally source filename.", 584 - "type": [ 585 - "string", 586 - "null" 587 - ] 588 - }, 589 - "validation_results": { 590 - "description": "Validation results (Ingredient.V3)", 591 - "anyOf": [ 592 - { 593 - "$ref": "#/definitions/ValidationResults" 594 - }, 595 - { 596 - "type": "null" 597 - } 598 - ] 599 - }, 600 - "validation_status": { 601 - "description": "Validation status (Ingredient v1 & v2)", 602 - "type": [ 603 - "array", 604 - "null" 605 - ], 606 - "items": { 607 - "$ref": "#/definitions/ValidationStatus" 608 - } 609 - } 610 - } 611 - }, 612 - "IngredientDeltaValidationResult": { 613 - "description": "Represents any changes or deltas between the current and previous validation results for an ingredient's manifest.", 614 - "type": "object", 615 - "required": [ 616 - "ingredientAssertionURI", 617 - "validationDeltas" 618 - ], 619 - "properties": { 620 - "ingredientAssertionURI": { 621 - "description": "JUMBF URI reference to the ingredient assertion", 622 - "type": "string" 623 - }, 624 - "validationDeltas": { 625 - "description": "Validation results for the ingredient's active manifest", 626 - "allOf": [ 627 - { 628 - "$ref": "#/definitions/StatusCodes" 629 - } 630 - ] 631 - } 632 - } 633 - }, 634 - "Item": { 635 - "description": "Description of the boundaries of an identified range.", 636 - "type": "object", 637 - "required": [ 638 - "identifier", 639 - "value" 640 - ], 641 - "properties": { 642 - "identifier": { 643 - "description": "The container-specific term used to identify items, such as \"track_id\" for MP4 or \"item_ID\" for HEIF.", 644 - "type": "string" 645 - }, 646 - "value": { 647 - "description": "The value of the identifier, e.g. a value of \"2\" for an identifier of \"track_id\" would imply track 2 of the asset.", 648 - "type": "string" 649 - } 650 - } 651 - }, 652 - "Range": { 653 - "description": "A spatial, temporal, frame, or textual range describing the region of interest.", 654 - "type": "object", 655 - "required": [ 656 - "type" 657 - ], 658 - "properties": { 659 - "frame": { 660 - "description": "A frame range.", 661 - "anyOf": [ 662 - { 663 - "$ref": "#/definitions/Frame" 664 - }, 665 - { 666 - "type": "null" 667 - } 668 - ] 669 - }, 670 - "item": { 671 - "description": "A item identifier.", 672 - "anyOf": [ 673 - { 674 - "$ref": "#/definitions/Item" 675 - }, 676 - { 677 - "type": "null" 678 - } 679 - ] 680 - }, 681 - "shape": { 682 - "description": "A spatial range.", 683 - "anyOf": [ 684 - { 685 - "$ref": "#/definitions/Shape" 686 - }, 687 - { 688 - "type": "null" 689 - } 690 - ] 691 - }, 692 - "text": { 693 - "description": "A textual range.", 694 - "anyOf": [ 695 - { 696 - "$ref": "#/definitions/Text" 697 - }, 698 - { 699 - "type": "null" 700 - } 701 - ] 702 - }, 703 - "time": { 704 - "description": "A temporal range.", 705 - "anyOf": [ 706 - { 707 - "$ref": "#/definitions/Time" 708 - }, 709 - { 710 - "type": "null" 711 - } 712 - ] 713 - }, 714 - "type": { 715 - "description": "The type of range of interest.", 716 - "allOf": [ 717 - { 718 - "$ref": "#/definitions/RangeType" 719 - } 720 - ] 721 - } 722 - } 723 - }, 724 - "RangeType": { 725 - "description": "The type of range for the region of interest.", 726 - "oneOf": [ 727 - { 728 - "description": "A spatial range, see [`Shape`] for more details.", 729 - "type": "string", 730 - "enum": [ 731 - "spatial" 732 - ] 733 - }, 734 - { 735 - "description": "A temporal range, see [`Time`] for more details.", 736 - "type": "string", 737 - "enum": [ 738 - "temporal" 739 - ] 740 - }, 741 - { 742 - "description": "A spatial range, see [`Frame`] for more details.", 743 - "type": "string", 744 - "enum": [ 745 - "frame" 746 - ] 747 - }, 748 - { 749 - "description": "A textual range, see [`Text`] for more details.", 750 - "type": "string", 751 - "enum": [ 752 - "textual" 753 - ] 754 - }, 755 - { 756 - "description": "A range identified by a specific identifier and value, see [`Item`] for more details.", 757 - "type": "string", 758 - "enum": [ 759 - "identified" 760 - ] 761 - } 762 - ] 763 - }, 764 - "RegionOfInterest": { 765 - "description": "A region of interest within an asset describing the change.\n\nThis struct can be used from [`Action::changes`][crate::assertions::Action::changes] or [`AssertionMetadata::region_of_interest`][crate::assertions::AssertionMetadata::region_of_interest].", 766 - "type": "object", 767 - "required": [ 768 - "region" 769 - ], 770 - "properties": { 771 - "description": { 772 - "description": "A free-text string.", 773 - "type": [ 774 - "string", 775 - "null" 776 - ] 777 - }, 778 - "identifier": { 779 - "description": "A free-text string representing a machine-readable, unique to this assertion, identifier for the region.", 780 - "type": [ 781 - "string", 782 - "null" 783 - ] 784 - }, 785 - "metadata": { 786 - "description": "Additional information about the asset.", 787 - "anyOf": [ 788 - { 789 - "$ref": "#/definitions/AssertionMetadata" 790 - }, 791 - { 792 - "type": "null" 793 - } 794 - ] 795 - }, 796 - "name": { 797 - "description": "A free-text string representing a human-readable name for the region which might be used in a user interface.", 798 - "type": [ 799 - "string", 800 - "null" 801 - ] 802 - }, 803 - "region": { 804 - "description": "A range describing the region of interest for the specific asset.", 805 - "type": "array", 806 - "items": { 807 - "$ref": "#/definitions/Range" 808 - } 809 - }, 810 - "role": { 811 - "description": "A value from our controlled vocabulary or an entity-specific value (e.g., com.litware.coolArea) that represents the role of a region among other regions.", 812 - "anyOf": [ 813 - { 814 - "$ref": "#/definitions/Role" 815 - }, 816 - { 817 - "type": "null" 818 - } 819 - ] 820 - }, 821 - "type": { 822 - "description": "A value from a controlled vocabulary such as <https://cv.iptc.org/newscodes/imageregiontype/> or an entity-specific value (e.g., com.litware.newType) that represents the type of thing(s) depicted by a region.\n\nNote this field serializes/deserializes into the name `type`.", 823 - "type": [ 824 - "string", 825 - "null" 826 - ] 827 - } 828 - } 829 - }, 830 - "Relationship": { 831 - "description": "The relationship of the ingredient to the current asset.", 832 - "oneOf": [ 833 - { 834 - "description": "The current asset is derived from this ingredient.", 835 - "type": "string", 836 - "enum": [ 837 - "parentOf" 838 - ] 839 - }, 840 - { 841 - "description": "The current asset is a part of this ingredient.", 842 - "type": "string", 843 - "enum": [ 844 - "componentOf" 845 - ] 846 - }, 847 - { 848 - "description": "The ingredient was used as an input to a computational process to create or modify the asset.", 849 - "type": "string", 850 - "enum": [ 851 - "inputTo" 852 - ] 853 - } 854 - ] 855 - }, 856 - "ResourceRef": { 857 - "description": "A reference to a resource to be used in JSON serialization.\n\nThe underlying data can be read as a stream via [`Reader::resource_to_stream`][crate::Reader::resource_to_stream].", 858 - "type": "object", 859 - "required": [ 860 - "format", 861 - "identifier" 862 - ], 863 - "properties": { 864 - "alg": { 865 - "description": "The algorithm used to hash the resource (if applicable).", 866 - "type": [ 867 - "string", 868 - "null" 869 - ] 870 - }, 871 - "data_types": { 872 - "description": "More detailed data types as defined in the C2PA spec.", 873 - "type": [ 874 - "array", 875 - "null" 876 - ], 877 - "items": { 878 - "$ref": "#/definitions/AssetType" 879 - } 880 - }, 881 - "format": { 882 - "description": "The mime type of the referenced resource.", 883 - "type": "string" 884 - }, 885 - "hash": { 886 - "description": "The hash of the resource (if applicable).", 887 - "type": [ 888 - "string", 889 - "null" 890 - ] 891 - }, 892 - "identifier": { 893 - "description": "A URI that identifies the resource as referenced from the manifest.\n\nThis may be a JUMBF URI, a file path, a URL or any other string. Relative JUMBF URIs will be resolved with the manifest label. Relative file paths will be resolved with the base path if provided.", 894 - "type": "string" 895 - } 896 - } 897 - }, 898 - "ResourceStore": { 899 - "description": "Resource store to contain binary objects referenced from JSON serializable structures", 900 - "type": "object", 901 - "required": [ 902 - "resources" 903 - ], 904 - "properties": { 905 - "base_path": { 906 - "type": [ 907 - "string", 908 - "null" 909 - ] 910 - }, 911 - "label": { 912 - "type": [ 913 - "string", 914 - "null" 915 - ] 916 - }, 917 - "resources": { 918 - "type": "object", 919 - "additionalProperties": { 920 - "type": "array", 921 - "items": { 922 - "type": "integer", 923 - "format": "uint8", 924 - "minimum": 0.0 925 - } 926 - } 927 - } 928 - } 929 - }, 930 - "ReviewRating": { 931 - "description": "A rating on an Assertion.\n\nSee <https://c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_review_ratings>.", 932 - "type": "object", 933 - "required": [ 934 - "explanation", 935 - "value" 936 - ], 937 - "properties": { 938 - "code": { 939 - "type": [ 940 - "string", 941 - "null" 942 - ] 943 - }, 944 - "explanation": { 945 - "type": "string" 946 - }, 947 - "value": { 948 - "type": "integer", 949 - "format": "uint8", 950 - "minimum": 0.0 951 - } 952 - } 953 - }, 954 - "Role": { 955 - "description": "A role describing the region.", 956 - "oneOf": [ 957 - { 958 - "description": "Arbitrary area worth identifying.", 959 - "type": "string", 960 - "enum": [ 961 - "c2pa.areaOfInterest" 962 - ] 963 - }, 964 - { 965 - "description": "This area is all that is left after a crop action.", 966 - "type": "string", 967 - "enum": [ 968 - "c2pa.cropped" 969 - ] 970 - }, 971 - { 972 - "description": "This area has had edits applied to it.", 973 - "type": "string", 974 - "enum": [ 975 - "c2pa.edited" 976 - ] 977 - }, 978 - { 979 - "description": "The area where an ingredient was placed/added.", 980 - "type": "string", 981 - "enum": [ 982 - "c2pa.placed" 983 - ] 984 - }, 985 - { 986 - "description": "Something in this area was redacted.", 987 - "type": "string", 988 - "enum": [ 989 - "c2pa.redacted" 990 - ] 991 - }, 992 - { 993 - "description": "Area specific to a subject (human or not).", 994 - "type": "string", 995 - "enum": [ 996 - "c2pa.subjectArea" 997 - ] 998 - }, 999 - { 1000 - "description": "A range of information was removed/deleted.", 1001 - "type": "string", 1002 - "enum": [ 1003 - "c2pa.deleted" 1004 - ] 1005 - }, 1006 - { 1007 - "description": "Styling was applied to this area.", 1008 - "type": "string", 1009 - "enum": [ 1010 - "c2pa.styled" 1011 - ] 1012 - }, 1013 - { 1014 - "description": "Invisible watermarking was applied to this area for the purpose of soft binding.", 1015 - "type": "string", 1016 - "enum": [ 1017 - "c2pa.watermarked" 1018 - ] 1019 - } 1020 - ] 1021 - }, 1022 - "Shape": { 1023 - "description": "A spatial range representing rectangle, circle, or a polygon.", 1024 - "type": "object", 1025 - "required": [ 1026 - "origin", 1027 - "type", 1028 - "unit" 1029 - ], 1030 - "properties": { 1031 - "height": { 1032 - "description": "The height of a rectnagle.\n\nThis field can be ignored for circles and polygons.", 1033 - "type": [ 1034 - "number", 1035 - "null" 1036 - ], 1037 - "format": "double" 1038 - }, 1039 - "inside": { 1040 - "description": "If the range is inside the shape.\n\nThe default value is true.", 1041 - "type": [ 1042 - "boolean", 1043 - "null" 1044 - ] 1045 - }, 1046 - "origin": { 1047 - "description": "THe origin of the coordinate in the shape.", 1048 - "allOf": [ 1049 - { 1050 - "$ref": "#/definitions/Coordinate" 1051 - } 1052 - ] 1053 - }, 1054 - "type": { 1055 - "description": "The type of shape.", 1056 - "allOf": [ 1057 - { 1058 - "$ref": "#/definitions/ShapeType" 1059 - } 1060 - ] 1061 - }, 1062 - "unit": { 1063 - "description": "The type of unit for the shape range.", 1064 - "allOf": [ 1065 - { 1066 - "$ref": "#/definitions/UnitType" 1067 - } 1068 - ] 1069 - }, 1070 - "vertices": { 1071 - "description": "The vertices of the polygon.\n\nThis field can be ignored for rectangles and circles.", 1072 - "type": [ 1073 - "array", 1074 - "null" 1075 - ], 1076 - "items": { 1077 - "$ref": "#/definitions/Coordinate" 1078 - } 1079 - }, 1080 - "width": { 1081 - "description": "The width for rectangles or diameter for circles.\n\nThis field can be ignored for polygons.", 1082 - "type": [ 1083 - "number", 1084 - "null" 1085 - ], 1086 - "format": "double" 1087 - } 1088 - } 1089 - }, 1090 - "ShapeType": { 1091 - "description": "The type of shape for the range.", 1092 - "oneOf": [ 1093 - { 1094 - "description": "A rectangle.", 1095 - "type": "string", 1096 - "enum": [ 1097 - "rectangle" 1098 - ] 1099 - }, 1100 - { 1101 - "description": "A circle.", 1102 - "type": "string", 1103 - "enum": [ 1104 - "circle" 1105 - ] 1106 - }, 1107 - { 1108 - "description": "A polygon.", 1109 - "type": "string", 1110 - "enum": [ 1111 - "polygon" 1112 - ] 1113 - } 1114 - ] 1115 - }, 1116 - "StatusCodes": { 1117 - "description": "Contains a set of success, informational, and failure validation status codes.", 1118 - "type": "object", 1119 - "required": [ 1120 - "failure", 1121 - "informational", 1122 - "success" 1123 - ], 1124 - "properties": { 1125 - "failure": { 1126 - "type": "array", 1127 - "items": { 1128 - "$ref": "#/definitions/ValidationStatus" 1129 - } 1130 - }, 1131 - "informational": { 1132 - "type": "array", 1133 - "items": { 1134 - "$ref": "#/definitions/ValidationStatus" 1135 - } 1136 - }, 1137 - "success": { 1138 - "type": "array", 1139 - "items": { 1140 - "$ref": "#/definitions/ValidationStatus" 1141 - } 1142 - } 1143 - } 1144 - }, 1145 - "Text": { 1146 - "description": "A textual range representing multiple (possibly discontinuous) ranges of text.", 1147 - "type": "object", 1148 - "required": [ 1149 - "selectors" 1150 - ], 1151 - "properties": { 1152 - "selectors": { 1153 - "description": "The ranges of text to select.", 1154 - "type": "array", 1155 - "items": { 1156 - "$ref": "#/definitions/TextSelectorRange" 1157 - } 1158 - } 1159 - } 1160 - }, 1161 - "TextSelector": { 1162 - "description": "Selects a range of text via a fragment identifier.\n\nThis is modeled after the W3C Web Annotation selector model.", 1163 - "type": "object", 1164 - "required": [ 1165 - "fragment" 1166 - ], 1167 - "properties": { 1168 - "end": { 1169 - "description": "The end character offset or the end of the fragment if not present.", 1170 - "type": [ 1171 - "integer", 1172 - "null" 1173 - ], 1174 - "format": "int32" 1175 - }, 1176 - "fragment": { 1177 - "description": "Fragment identifier as per RFC3023 (XML) or ISO 32000-2 (PDF), Annex O.", 1178 - "type": "string" 1179 - }, 1180 - "start": { 1181 - "description": "The start character offset or the start of the fragment if not present.", 1182 - "type": [ 1183 - "integer", 1184 - "null" 1185 - ], 1186 - "format": "int32" 1187 - } 1188 - } 1189 - }, 1190 - "TextSelectorRange": { 1191 - "description": "One or two [`TextSelector`][TextSelector] identifiying the range to select.", 1192 - "type": "object", 1193 - "required": [ 1194 - "selector" 1195 - ], 1196 - "properties": { 1197 - "end": { 1198 - "description": "The end of the text range.", 1199 - "anyOf": [ 1200 - { 1201 - "$ref": "#/definitions/TextSelector" 1202 - }, 1203 - { 1204 - "type": "null" 1205 - } 1206 - ] 1207 - }, 1208 - "selector": { 1209 - "description": "The start (or entire) text range.", 1210 - "allOf": [ 1211 - { 1212 - "$ref": "#/definitions/TextSelector" 1213 - } 1214 - ] 1215 - } 1216 - } 1217 - }, 1218 - "Time": { 1219 - "description": "A temporal range representing a starting time to an ending time.", 1220 - "type": "object", 1221 - "properties": { 1222 - "end": { 1223 - "description": "The end time or the end of the asset if not present.", 1224 - "type": [ 1225 - "string", 1226 - "null" 1227 - ] 1228 - }, 1229 - "start": { 1230 - "description": "The start time or the start of the asset if not present.", 1231 - "type": [ 1232 - "string", 1233 - "null" 1234 - ] 1235 - }, 1236 - "type": { 1237 - "description": "The type of time.", 1238 - "default": "npt", 1239 - "allOf": [ 1240 - { 1241 - "$ref": "#/definitions/TimeType" 1242 - } 1243 - ] 1244 - } 1245 - } 1246 - }, 1247 - "TimeType": { 1248 - "description": "The type of time.", 1249 - "oneOf": [ 1250 - { 1251 - "description": "Times are described using Normal Play Time (npt) as described in RFC 2326.", 1252 - "type": "string", 1253 - "enum": [ 1254 - "npt" 1255 - ] 1256 - } 1257 - ] 1258 - }, 1259 - "UnitType": { 1260 - "description": "The type of unit for the range.", 1261 - "oneOf": [ 1262 - { 1263 - "description": "Use pixels.", 1264 - "type": "string", 1265 - "enum": [ 1266 - "pixel" 1267 - ] 1268 - }, 1269 - { 1270 - "description": "Use percentage.", 1271 - "type": "string", 1272 - "enum": [ 1273 - "percent" 1274 - ] 1275 - } 1276 - ] 1277 - }, 1278 - "UriOrResource": { 1279 - "anyOf": [ 1280 - { 1281 - "$ref": "#/definitions/ResourceRef" 1282 - }, 1283 - { 1284 - "$ref": "#/definitions/HashedUri" 1285 - } 1286 - ] 1287 - }, 1288 - "ValidationResults": { 1289 - "description": "A map of validation results for a manifest store.\n\nThe map contains the validation results for the active manifest and any ingredient deltas. It is normal for there to be many", 1290 - "type": "object", 1291 - "properties": { 1292 - "activeManifest": { 1293 - "anyOf": [ 1294 - { 1295 - "$ref": "#/definitions/StatusCodes" 1296 - }, 1297 - { 1298 - "type": "null" 1299 - } 1300 - ] 1301 - }, 1302 - "ingredientDeltas": { 1303 - "type": [ 1304 - "array", 1305 - "null" 1306 - ], 1307 - "items": { 1308 - "$ref": "#/definitions/IngredientDeltaValidationResult" 1309 - } 1310 - } 1311 - } 1312 - }, 1313 - "ValidationStatus": { 1314 - "description": "A `ValidationStatus` struct describes the validation status of a specific part of a manifest.\n\nSee <https://c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_existing_manifests>.", 1315 - "type": "object", 1316 - "required": [ 1317 - "code" 1318 - ], 1319 - "properties": { 1320 - "code": { 1321 - "type": "string" 1322 - }, 1323 - "explanation": { 1324 - "type": [ 1325 - "string", 1326 - "null" 1327 - ] 1328 - }, 1329 - "success": { 1330 - "writeOnly": true, 1331 - "type": [ 1332 - "boolean", 1333 - "null" 1334 - ] 1335 - }, 1336 - "url": { 1337 - "type": [ 1338 - "string", 1339 - "null" 1340 - ] 1341 - } 1342 - } 1343 - } 1344 - } 1345 - }
-1271
pkg/c2pa/ManifestDefinition.schema.json
··· 1 - { 2 - "$schema": "http://json-schema.org/draft-07/schema#", 3 - "title": "ManifestDefinition", 4 - "description": "Use a ManifestDefinition to define a manifest and to build a `ManifestStore`. A manifest is a collection of ingredients and assertions used to define a claim that can be signed and embedded into a file.", 5 - "type": "object", 6 - "properties": { 7 - "assertions": { 8 - "description": "A list of assertions", 9 - "default": [], 10 - "type": "array", 11 - "items": { 12 - "$ref": "#/definitions/AssertionDefinition" 13 - } 14 - }, 15 - "claim_generator_info": { 16 - "description": "Claim Generator Info is always required with at least one entry", 17 - "default": [ 18 - { 19 - "name": "c2pa-rs", 20 - "version": "0.58.0" 21 - } 22 - ], 23 - "type": "array", 24 - "items": { 25 - "$ref": "#/definitions/ClaimGeneratorInfo" 26 - } 27 - }, 28 - "claim_version": { 29 - "description": "The version of the claim. Defaults to 1.", 30 - "type": [ 31 - "integer", 32 - "null" 33 - ], 34 - "format": "uint8", 35 - "minimum": 0.0 36 - }, 37 - "format": { 38 - "description": "The format of the source file as a MIME type.", 39 - "default": "application/octet-stream", 40 - "type": "string" 41 - }, 42 - "ingredients": { 43 - "description": "A List of ingredients", 44 - "default": [], 45 - "type": "array", 46 - "items": { 47 - "$ref": "#/definitions/Ingredient" 48 - } 49 - }, 50 - "instance_id": { 51 - "description": "Instance ID from `xmpMM:InstanceID` in XMP metadata.", 52 - "default": "xmp:iid:36dc43ae-f0d2-4b76-a04f-29ee2f27d67a", 53 - "type": "string" 54 - }, 55 - "label": { 56 - "description": "Allows you to pre-define the manifest label, which must be unique. Not intended for general use. If not set, it will be assigned automatically.", 57 - "type": [ 58 - "string", 59 - "null" 60 - ] 61 - }, 62 - "metadata": { 63 - "description": "Optional manifest metadata. This will be deprecated in the future; not recommended to use.", 64 - "type": [ 65 - "array", 66 - "null" 67 - ], 68 - "items": { 69 - "$ref": "#/definitions/AssertionMetadata" 70 - } 71 - }, 72 - "redactions": { 73 - "description": "A list of redactions - URIs to redacted assertions.", 74 - "type": [ 75 - "array", 76 - "null" 77 - ], 78 - "items": { 79 - "type": "string" 80 - } 81 - }, 82 - "thumbnail": { 83 - "description": "An optional ResourceRef to a thumbnail image that represents the asset that was signed. Must be available when the manifest is signed.", 84 - "anyOf": [ 85 - { 86 - "$ref": "#/definitions/ResourceRef" 87 - }, 88 - { 89 - "type": "null" 90 - } 91 - ] 92 - }, 93 - "title": { 94 - "description": "A human-readable title, generally source filename.", 95 - "type": [ 96 - "string", 97 - "null" 98 - ] 99 - }, 100 - "vendor": { 101 - "description": "Optional prefix added to the generated Manifest Label This is typically a reverse domain name.", 102 - "type": [ 103 - "string", 104 - "null" 105 - ] 106 - } 107 - }, 108 - "definitions": { 109 - "Actor": { 110 - "description": "Identifies a person responsible for an action.", 111 - "type": "object", 112 - "properties": { 113 - "credentials": { 114 - "description": "List of references to W3C Verifiable Credentials.", 115 - "type": [ 116 - "array", 117 - "null" 118 - ], 119 - "items": { 120 - "$ref": "#/definitions/HashedUri" 121 - } 122 - }, 123 - "identifier": { 124 - "description": "An identifier for a human actor, used when the \"type\" is `humanEntry.identified`.", 125 - "type": [ 126 - "string", 127 - "null" 128 - ] 129 - } 130 - } 131 - }, 132 - "AssertionData": { 133 - "description": "This allows the assertion to be expressed as CBOR or JSON. The default is CBOR unless you specify that an assertion should be JSON.", 134 - "anyOf": [ 135 - true 136 - ] 137 - }, 138 - "AssertionDefinition": { 139 - "description": "Defines an assertion that consists of a label that can be either a C2PA-defined assertion label or a custom label in reverse domain format.", 140 - "type": "object", 141 - "required": [ 142 - "data", 143 - "label" 144 - ], 145 - "properties": { 146 - "data": { 147 - "$ref": "#/definitions/AssertionData" 148 - }, 149 - "label": { 150 - "type": "string" 151 - } 152 - } 153 - }, 154 - "AssertionMetadata": { 155 - "description": "The AssertionMetadata structure can be used as part of other assertions or on its own to reference others", 156 - "type": "object", 157 - "properties": { 158 - "dataSource": { 159 - "anyOf": [ 160 - { 161 - "$ref": "#/definitions/DataSource" 162 - }, 163 - { 164 - "type": "null" 165 - } 166 - ] 167 - }, 168 - "dateTime": { 169 - "anyOf": [ 170 - { 171 - "$ref": "#/definitions/DateT" 172 - }, 173 - { 174 - "type": "null" 175 - } 176 - ] 177 - }, 178 - "reference": { 179 - "anyOf": [ 180 - { 181 - "$ref": "#/definitions/HashedUri" 182 - }, 183 - { 184 - "type": "null" 185 - } 186 - ] 187 - }, 188 - "regionOfInterest": { 189 - "anyOf": [ 190 - { 191 - "$ref": "#/definitions/RegionOfInterest" 192 - }, 193 - { 194 - "type": "null" 195 - } 196 - ] 197 - }, 198 - "reviewRatings": { 199 - "type": [ 200 - "array", 201 - "null" 202 - ], 203 - "items": { 204 - "$ref": "#/definitions/ReviewRating" 205 - } 206 - } 207 - } 208 - }, 209 - "AssetType": { 210 - "type": "object", 211 - "required": [ 212 - "type" 213 - ], 214 - "properties": { 215 - "type": { 216 - "type": "string" 217 - }, 218 - "version": { 219 - "type": [ 220 - "string", 221 - "null" 222 - ] 223 - } 224 - } 225 - }, 226 - "ClaimGeneratorInfo": { 227 - "description": "Description of the claim generator, or the software used in generating the claim.\n\nThis structure is also used for actions softwareAgent", 228 - "type": "object", 229 - "required": [ 230 - "name" 231 - ], 232 - "properties": { 233 - "icon": { 234 - "description": "hashed URI to the icon (either embedded or remote)", 235 - "anyOf": [ 236 - { 237 - "$ref": "#/definitions/UriOrResource" 238 - }, 239 - { 240 - "type": "null" 241 - } 242 - ] 243 - }, 244 - "name": { 245 - "description": "A human readable string naming the claim_generator", 246 - "type": "string" 247 - }, 248 - "operating_system": { 249 - "description": "A human readable string of the OS the claim generator is running on", 250 - "type": [ 251 - "string", 252 - "null" 253 - ] 254 - }, 255 - "version": { 256 - "description": "A human readable string of the product's version", 257 - "type": [ 258 - "string", 259 - "null" 260 - ] 261 - } 262 - }, 263 - "additionalProperties": true 264 - }, 265 - "Coordinate": { 266 - "description": "An x, y coordinate used for specifying vertices in polygons.", 267 - "type": "object", 268 - "required": [ 269 - "x", 270 - "y" 271 - ], 272 - "properties": { 273 - "x": { 274 - "description": "The coordinate along the x-axis.", 275 - "type": "number", 276 - "format": "double" 277 - }, 278 - "y": { 279 - "description": "The coordinate along the y-axis.", 280 - "type": "number", 281 - "format": "double" 282 - } 283 - } 284 - }, 285 - "DataSource": { 286 - "description": "A description of the source for assertion data", 287 - "type": "object", 288 - "required": [ 289 - "type" 290 - ], 291 - "properties": { 292 - "actors": { 293 - "description": "A list of [`Actor`]s associated with this source.", 294 - "type": [ 295 - "array", 296 - "null" 297 - ], 298 - "items": { 299 - "$ref": "#/definitions/Actor" 300 - } 301 - }, 302 - "details": { 303 - "description": "A human-readable string giving details about the source of the assertion data.", 304 - "type": [ 305 - "string", 306 - "null" 307 - ] 308 - }, 309 - "type": { 310 - "description": "A value from among the enumerated list indicating the source of the assertion.", 311 - "type": "string" 312 - } 313 - } 314 - }, 315 - "DateT": { 316 - "type": "string" 317 - }, 318 - "Frame": { 319 - "description": "A frame range representing starting and ending frames or pages.\n\nIf both `start` and `end` are missing, the frame will span the entire asset.", 320 - "type": "object", 321 - "properties": { 322 - "end": { 323 - "description": "The end of the frame inclusive or the end of the asset if not present.", 324 - "type": [ 325 - "integer", 326 - "null" 327 - ], 328 - "format": "int32" 329 - }, 330 - "start": { 331 - "description": "The start of the frame or the end of the asset if not present.\n\nThe first frame/page starts at 0.", 332 - "type": [ 333 - "integer", 334 - "null" 335 - ], 336 - "format": "int32" 337 - } 338 - } 339 - }, 340 - "HashedUri": { 341 - "description": "A `HashedUri` provides a reference to content available within the same manifest store.\n\nThis is described in [§8.3, URI References], of the C2PA Technical Specification.\n\n[§8.3, URI References]: https://c2pa.org/specifications/specifications/2.1/specs/C2PA_Specification.html#_uri_references", 342 - "type": "object", 343 - "required": [ 344 - "hash", 345 - "url" 346 - ], 347 - "properties": { 348 - "alg": { 349 - "description": "A string identifying the cryptographic hash algorithm used to compute the hash", 350 - "type": [ 351 - "string", 352 - "null" 353 - ] 354 - }, 355 - "hash": { 356 - "description": "Byte string containing the hash value", 357 - "type": "array", 358 - "items": { 359 - "type": "integer", 360 - "format": "uint8", 361 - "minimum": 0.0 362 - } 363 - }, 364 - "url": { 365 - "description": "JUMBF URI reference", 366 - "type": "string" 367 - } 368 - } 369 - }, 370 - "Ingredient": { 371 - "description": "An `Ingredient` is any external asset that has been used in the creation of an asset.", 372 - "type": "object", 373 - "properties": { 374 - "active_manifest": { 375 - "description": "The active manifest label (if one exists).\n\nIf this ingredient has a [`ManifestStore`], this will hold the label of the active [`Manifest`].\n\n[`Manifest`]: crate::Manifest [`ManifestStore`]: crate::ManifestStore", 376 - "type": [ 377 - "string", 378 - "null" 379 - ] 380 - }, 381 - "data": { 382 - "description": "A reference to the actual data of the ingredient.", 383 - "anyOf": [ 384 - { 385 - "$ref": "#/definitions/ResourceRef" 386 - }, 387 - { 388 - "type": "null" 389 - } 390 - ] 391 - }, 392 - "data_types": { 393 - "description": "Additional information about the data's type to the ingredient V2 structure.", 394 - "type": [ 395 - "array", 396 - "null" 397 - ], 398 - "items": { 399 - "$ref": "#/definitions/AssetType" 400 - } 401 - }, 402 - "description": { 403 - "description": "Additional description of the ingredient.", 404 - "type": [ 405 - "string", 406 - "null" 407 - ] 408 - }, 409 - "document_id": { 410 - "description": "Document ID from `xmpMM:DocumentID` in XMP metadata.", 411 - "type": [ 412 - "string", 413 - "null" 414 - ] 415 - }, 416 - "format": { 417 - "description": "The format of the source file as a MIME type.", 418 - "type": [ 419 - "string", 420 - "null" 421 - ] 422 - }, 423 - "hash": { 424 - "description": "An optional hash of the asset to prevent duplicates.", 425 - "type": [ 426 - "string", 427 - "null" 428 - ] 429 - }, 430 - "informational_URI": { 431 - "description": "URI to an informational page about the ingredient or its data.", 432 - "type": [ 433 - "string", 434 - "null" 435 - ] 436 - }, 437 - "instance_id": { 438 - "description": "Instance ID from `xmpMM:InstanceID` in XMP metadata.", 439 - "type": [ 440 - "string", 441 - "null" 442 - ] 443 - }, 444 - "label": { 445 - "description": "The ingredient's label as assigned in the manifest.", 446 - "type": [ 447 - "string", 448 - "null" 449 - ] 450 - }, 451 - "manifest_data": { 452 - "description": "A [`ManifestStore`] from the source asset extracted as a binary C2PA blob.\n\n[`ManifestStore`]: crate::ManifestStore", 453 - "anyOf": [ 454 - { 455 - "$ref": "#/definitions/ResourceRef" 456 - }, 457 - { 458 - "type": "null" 459 - } 460 - ] 461 - }, 462 - "metadata": { 463 - "description": "Any additional [`Metadata`] as defined in the C2PA spec.\n\n[`Metadata`]: crate::Metadata", 464 - "anyOf": [ 465 - { 466 - "$ref": "#/definitions/AssertionMetadata" 467 - }, 468 - { 469 - "type": "null" 470 - } 471 - ] 472 - }, 473 - "provenance": { 474 - "description": "URI from `dcterms:provenance` in XMP metadata.", 475 - "type": [ 476 - "string", 477 - "null" 478 - ] 479 - }, 480 - "relationship": { 481 - "description": "Set to `ParentOf` if this is the parent ingredient.\n\nThere can only be one parent ingredient in the ingredients.", 482 - "default": "componentOf", 483 - "allOf": [ 484 - { 485 - "$ref": "#/definitions/Relationship" 486 - } 487 - ] 488 - }, 489 - "resources": { 490 - "readOnly": true, 491 - "allOf": [ 492 - { 493 - "$ref": "#/definitions/ResourceStore" 494 - } 495 - ] 496 - }, 497 - "thumbnail": { 498 - "description": "A thumbnail image capturing the visual state at the time of import.\n\nA tuple of thumbnail MIME format (for example `image/jpeg`) and binary bits of the image.", 499 - "anyOf": [ 500 - { 501 - "$ref": "#/definitions/ResourceRef" 502 - }, 503 - { 504 - "type": "null" 505 - } 506 - ] 507 - }, 508 - "title": { 509 - "description": "A human-readable title, generally source filename.", 510 - "type": [ 511 - "string", 512 - "null" 513 - ] 514 - }, 515 - "validation_results": { 516 - "description": "Validation results (Ingredient.V3)", 517 - "anyOf": [ 518 - { 519 - "$ref": "#/definitions/ValidationResults" 520 - }, 521 - { 522 - "type": "null" 523 - } 524 - ] 525 - }, 526 - "validation_status": { 527 - "description": "Validation status (Ingredient v1 & v2)", 528 - "type": [ 529 - "array", 530 - "null" 531 - ], 532 - "items": { 533 - "$ref": "#/definitions/ValidationStatus" 534 - } 535 - } 536 - } 537 - }, 538 - "IngredientDeltaValidationResult": { 539 - "description": "Represents any changes or deltas between the current and previous validation results for an ingredient's manifest.", 540 - "type": "object", 541 - "required": [ 542 - "ingredientAssertionURI", 543 - "validationDeltas" 544 - ], 545 - "properties": { 546 - "ingredientAssertionURI": { 547 - "description": "JUMBF URI reference to the ingredient assertion", 548 - "type": "string" 549 - }, 550 - "validationDeltas": { 551 - "description": "Validation results for the ingredient's active manifest", 552 - "allOf": [ 553 - { 554 - "$ref": "#/definitions/StatusCodes" 555 - } 556 - ] 557 - } 558 - } 559 - }, 560 - "Item": { 561 - "description": "Description of the boundaries of an identified range.", 562 - "type": "object", 563 - "required": [ 564 - "identifier", 565 - "value" 566 - ], 567 - "properties": { 568 - "identifier": { 569 - "description": "The container-specific term used to identify items, such as \"track_id\" for MP4 or \"item_ID\" for HEIF.", 570 - "type": "string" 571 - }, 572 - "value": { 573 - "description": "The value of the identifier, e.g. a value of \"2\" for an identifier of \"track_id\" would imply track 2 of the asset.", 574 - "type": "string" 575 - } 576 - } 577 - }, 578 - "Range": { 579 - "description": "A spatial, temporal, frame, or textual range describing the region of interest.", 580 - "type": "object", 581 - "required": [ 582 - "type" 583 - ], 584 - "properties": { 585 - "frame": { 586 - "description": "A frame range.", 587 - "anyOf": [ 588 - { 589 - "$ref": "#/definitions/Frame" 590 - }, 591 - { 592 - "type": "null" 593 - } 594 - ] 595 - }, 596 - "item": { 597 - "description": "A item identifier.", 598 - "anyOf": [ 599 - { 600 - "$ref": "#/definitions/Item" 601 - }, 602 - { 603 - "type": "null" 604 - } 605 - ] 606 - }, 607 - "shape": { 608 - "description": "A spatial range.", 609 - "anyOf": [ 610 - { 611 - "$ref": "#/definitions/Shape" 612 - }, 613 - { 614 - "type": "null" 615 - } 616 - ] 617 - }, 618 - "text": { 619 - "description": "A textual range.", 620 - "anyOf": [ 621 - { 622 - "$ref": "#/definitions/Text" 623 - }, 624 - { 625 - "type": "null" 626 - } 627 - ] 628 - }, 629 - "time": { 630 - "description": "A temporal range.", 631 - "anyOf": [ 632 - { 633 - "$ref": "#/definitions/Time" 634 - }, 635 - { 636 - "type": "null" 637 - } 638 - ] 639 - }, 640 - "type": { 641 - "description": "The type of range of interest.", 642 - "allOf": [ 643 - { 644 - "$ref": "#/definitions/RangeType" 645 - } 646 - ] 647 - } 648 - } 649 - }, 650 - "RangeType": { 651 - "description": "The type of range for the region of interest.", 652 - "oneOf": [ 653 - { 654 - "description": "A spatial range, see [`Shape`] for more details.", 655 - "type": "string", 656 - "enum": [ 657 - "spatial" 658 - ] 659 - }, 660 - { 661 - "description": "A temporal range, see [`Time`] for more details.", 662 - "type": "string", 663 - "enum": [ 664 - "temporal" 665 - ] 666 - }, 667 - { 668 - "description": "A spatial range, see [`Frame`] for more details.", 669 - "type": "string", 670 - "enum": [ 671 - "frame" 672 - ] 673 - }, 674 - { 675 - "description": "A textual range, see [`Text`] for more details.", 676 - "type": "string", 677 - "enum": [ 678 - "textual" 679 - ] 680 - }, 681 - { 682 - "description": "A range identified by a specific identifier and value, see [`Item`] for more details.", 683 - "type": "string", 684 - "enum": [ 685 - "identified" 686 - ] 687 - } 688 - ] 689 - }, 690 - "RegionOfInterest": { 691 - "description": "A region of interest within an asset describing the change.\n\nThis struct can be used from [`Action::changes`][crate::assertions::Action::changes] or [`AssertionMetadata::region_of_interest`][crate::assertions::AssertionMetadata::region_of_interest].", 692 - "type": "object", 693 - "required": [ 694 - "region" 695 - ], 696 - "properties": { 697 - "description": { 698 - "description": "A free-text string.", 699 - "type": [ 700 - "string", 701 - "null" 702 - ] 703 - }, 704 - "identifier": { 705 - "description": "A free-text string representing a machine-readable, unique to this assertion, identifier for the region.", 706 - "type": [ 707 - "string", 708 - "null" 709 - ] 710 - }, 711 - "metadata": { 712 - "description": "Additional information about the asset.", 713 - "anyOf": [ 714 - { 715 - "$ref": "#/definitions/AssertionMetadata" 716 - }, 717 - { 718 - "type": "null" 719 - } 720 - ] 721 - }, 722 - "name": { 723 - "description": "A free-text string representing a human-readable name for the region which might be used in a user interface.", 724 - "type": [ 725 - "string", 726 - "null" 727 - ] 728 - }, 729 - "region": { 730 - "description": "A range describing the region of interest for the specific asset.", 731 - "type": "array", 732 - "items": { 733 - "$ref": "#/definitions/Range" 734 - } 735 - }, 736 - "role": { 737 - "description": "A value from our controlled vocabulary or an entity-specific value (e.g., com.litware.coolArea) that represents the role of a region among other regions.", 738 - "anyOf": [ 739 - { 740 - "$ref": "#/definitions/Role" 741 - }, 742 - { 743 - "type": "null" 744 - } 745 - ] 746 - }, 747 - "type": { 748 - "description": "A value from a controlled vocabulary such as <https://cv.iptc.org/newscodes/imageregiontype/> or an entity-specific value (e.g., com.litware.newType) that represents the type of thing(s) depicted by a region.\n\nNote this field serializes/deserializes into the name `type`.", 749 - "type": [ 750 - "string", 751 - "null" 752 - ] 753 - } 754 - } 755 - }, 756 - "Relationship": { 757 - "description": "The relationship of the ingredient to the current asset.", 758 - "oneOf": [ 759 - { 760 - "description": "The current asset is derived from this ingredient.", 761 - "type": "string", 762 - "enum": [ 763 - "parentOf" 764 - ] 765 - }, 766 - { 767 - "description": "The current asset is a part of this ingredient.", 768 - "type": "string", 769 - "enum": [ 770 - "componentOf" 771 - ] 772 - }, 773 - { 774 - "description": "The ingredient was used as an input to a computational process to create or modify the asset.", 775 - "type": "string", 776 - "enum": [ 777 - "inputTo" 778 - ] 779 - } 780 - ] 781 - }, 782 - "ResourceRef": { 783 - "description": "A reference to a resource to be used in JSON serialization.\n\nThe underlying data can be read as a stream via [`Reader::resource_to_stream`][crate::Reader::resource_to_stream].", 784 - "type": "object", 785 - "required": [ 786 - "format", 787 - "identifier" 788 - ], 789 - "properties": { 790 - "alg": { 791 - "description": "The algorithm used to hash the resource (if applicable).", 792 - "type": [ 793 - "string", 794 - "null" 795 - ] 796 - }, 797 - "data_types": { 798 - "description": "More detailed data types as defined in the C2PA spec.", 799 - "type": [ 800 - "array", 801 - "null" 802 - ], 803 - "items": { 804 - "$ref": "#/definitions/AssetType" 805 - } 806 - }, 807 - "format": { 808 - "description": "The mime type of the referenced resource.", 809 - "type": "string" 810 - }, 811 - "hash": { 812 - "description": "The hash of the resource (if applicable).", 813 - "type": [ 814 - "string", 815 - "null" 816 - ] 817 - }, 818 - "identifier": { 819 - "description": "A URI that identifies the resource as referenced from the manifest.\n\nThis may be a JUMBF URI, a file path, a URL or any other string. Relative JUMBF URIs will be resolved with the manifest label. Relative file paths will be resolved with the base path if provided.", 820 - "type": "string" 821 - } 822 - } 823 - }, 824 - "ResourceStore": { 825 - "description": "Resource store to contain binary objects referenced from JSON serializable structures", 826 - "type": "object", 827 - "required": [ 828 - "resources" 829 - ], 830 - "properties": { 831 - "base_path": { 832 - "type": [ 833 - "string", 834 - "null" 835 - ] 836 - }, 837 - "label": { 838 - "type": [ 839 - "string", 840 - "null" 841 - ] 842 - }, 843 - "resources": { 844 - "type": "object", 845 - "additionalProperties": { 846 - "type": "array", 847 - "items": { 848 - "type": "integer", 849 - "format": "uint8", 850 - "minimum": 0.0 851 - } 852 - } 853 - } 854 - } 855 - }, 856 - "ReviewRating": { 857 - "description": "A rating on an Assertion.\n\nSee <https://c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_review_ratings>.", 858 - "type": "object", 859 - "required": [ 860 - "explanation", 861 - "value" 862 - ], 863 - "properties": { 864 - "code": { 865 - "type": [ 866 - "string", 867 - "null" 868 - ] 869 - }, 870 - "explanation": { 871 - "type": "string" 872 - }, 873 - "value": { 874 - "type": "integer", 875 - "format": "uint8", 876 - "minimum": 0.0 877 - } 878 - } 879 - }, 880 - "Role": { 881 - "description": "A role describing the region.", 882 - "oneOf": [ 883 - { 884 - "description": "Arbitrary area worth identifying.", 885 - "type": "string", 886 - "enum": [ 887 - "c2pa.areaOfInterest" 888 - ] 889 - }, 890 - { 891 - "description": "This area is all that is left after a crop action.", 892 - "type": "string", 893 - "enum": [ 894 - "c2pa.cropped" 895 - ] 896 - }, 897 - { 898 - "description": "This area has had edits applied to it.", 899 - "type": "string", 900 - "enum": [ 901 - "c2pa.edited" 902 - ] 903 - }, 904 - { 905 - "description": "The area where an ingredient was placed/added.", 906 - "type": "string", 907 - "enum": [ 908 - "c2pa.placed" 909 - ] 910 - }, 911 - { 912 - "description": "Something in this area was redacted.", 913 - "type": "string", 914 - "enum": [ 915 - "c2pa.redacted" 916 - ] 917 - }, 918 - { 919 - "description": "Area specific to a subject (human or not).", 920 - "type": "string", 921 - "enum": [ 922 - "c2pa.subjectArea" 923 - ] 924 - }, 925 - { 926 - "description": "A range of information was removed/deleted.", 927 - "type": "string", 928 - "enum": [ 929 - "c2pa.deleted" 930 - ] 931 - }, 932 - { 933 - "description": "Styling was applied to this area.", 934 - "type": "string", 935 - "enum": [ 936 - "c2pa.styled" 937 - ] 938 - }, 939 - { 940 - "description": "Invisible watermarking was applied to this area for the purpose of soft binding.", 941 - "type": "string", 942 - "enum": [ 943 - "c2pa.watermarked" 944 - ] 945 - } 946 - ] 947 - }, 948 - "Shape": { 949 - "description": "A spatial range representing rectangle, circle, or a polygon.", 950 - "type": "object", 951 - "required": [ 952 - "origin", 953 - "type", 954 - "unit" 955 - ], 956 - "properties": { 957 - "height": { 958 - "description": "The height of a rectnagle.\n\nThis field can be ignored for circles and polygons.", 959 - "type": [ 960 - "number", 961 - "null" 962 - ], 963 - "format": "double" 964 - }, 965 - "inside": { 966 - "description": "If the range is inside the shape.\n\nThe default value is true.", 967 - "type": [ 968 - "boolean", 969 - "null" 970 - ] 971 - }, 972 - "origin": { 973 - "description": "THe origin of the coordinate in the shape.", 974 - "allOf": [ 975 - { 976 - "$ref": "#/definitions/Coordinate" 977 - } 978 - ] 979 - }, 980 - "type": { 981 - "description": "The type of shape.", 982 - "allOf": [ 983 - { 984 - "$ref": "#/definitions/ShapeType" 985 - } 986 - ] 987 - }, 988 - "unit": { 989 - "description": "The type of unit for the shape range.", 990 - "allOf": [ 991 - { 992 - "$ref": "#/definitions/UnitType" 993 - } 994 - ] 995 - }, 996 - "vertices": { 997 - "description": "The vertices of the polygon.\n\nThis field can be ignored for rectangles and circles.", 998 - "type": [ 999 - "array", 1000 - "null" 1001 - ], 1002 - "items": { 1003 - "$ref": "#/definitions/Coordinate" 1004 - } 1005 - }, 1006 - "width": { 1007 - "description": "The width for rectangles or diameter for circles.\n\nThis field can be ignored for polygons.", 1008 - "type": [ 1009 - "number", 1010 - "null" 1011 - ], 1012 - "format": "double" 1013 - } 1014 - } 1015 - }, 1016 - "ShapeType": { 1017 - "description": "The type of shape for the range.", 1018 - "oneOf": [ 1019 - { 1020 - "description": "A rectangle.", 1021 - "type": "string", 1022 - "enum": [ 1023 - "rectangle" 1024 - ] 1025 - }, 1026 - { 1027 - "description": "A circle.", 1028 - "type": "string", 1029 - "enum": [ 1030 - "circle" 1031 - ] 1032 - }, 1033 - { 1034 - "description": "A polygon.", 1035 - "type": "string", 1036 - "enum": [ 1037 - "polygon" 1038 - ] 1039 - } 1040 - ] 1041 - }, 1042 - "StatusCodes": { 1043 - "description": "Contains a set of success, informational, and failure validation status codes.", 1044 - "type": "object", 1045 - "required": [ 1046 - "failure", 1047 - "informational", 1048 - "success" 1049 - ], 1050 - "properties": { 1051 - "failure": { 1052 - "type": "array", 1053 - "items": { 1054 - "$ref": "#/definitions/ValidationStatus" 1055 - } 1056 - }, 1057 - "informational": { 1058 - "type": "array", 1059 - "items": { 1060 - "$ref": "#/definitions/ValidationStatus" 1061 - } 1062 - }, 1063 - "success": { 1064 - "type": "array", 1065 - "items": { 1066 - "$ref": "#/definitions/ValidationStatus" 1067 - } 1068 - } 1069 - } 1070 - }, 1071 - "Text": { 1072 - "description": "A textual range representing multiple (possibly discontinuous) ranges of text.", 1073 - "type": "object", 1074 - "required": [ 1075 - "selectors" 1076 - ], 1077 - "properties": { 1078 - "selectors": { 1079 - "description": "The ranges of text to select.", 1080 - "type": "array", 1081 - "items": { 1082 - "$ref": "#/definitions/TextSelectorRange" 1083 - } 1084 - } 1085 - } 1086 - }, 1087 - "TextSelector": { 1088 - "description": "Selects a range of text via a fragment identifier.\n\nThis is modeled after the W3C Web Annotation selector model.", 1089 - "type": "object", 1090 - "required": [ 1091 - "fragment" 1092 - ], 1093 - "properties": { 1094 - "end": { 1095 - "description": "The end character offset or the end of the fragment if not present.", 1096 - "type": [ 1097 - "integer", 1098 - "null" 1099 - ], 1100 - "format": "int32" 1101 - }, 1102 - "fragment": { 1103 - "description": "Fragment identifier as per RFC3023 (XML) or ISO 32000-2 (PDF), Annex O.", 1104 - "type": "string" 1105 - }, 1106 - "start": { 1107 - "description": "The start character offset or the start of the fragment if not present.", 1108 - "type": [ 1109 - "integer", 1110 - "null" 1111 - ], 1112 - "format": "int32" 1113 - } 1114 - } 1115 - }, 1116 - "TextSelectorRange": { 1117 - "description": "One or two [`TextSelector`][TextSelector] identifiying the range to select.", 1118 - "type": "object", 1119 - "required": [ 1120 - "selector" 1121 - ], 1122 - "properties": { 1123 - "end": { 1124 - "description": "The end of the text range.", 1125 - "anyOf": [ 1126 - { 1127 - "$ref": "#/definitions/TextSelector" 1128 - }, 1129 - { 1130 - "type": "null" 1131 - } 1132 - ] 1133 - }, 1134 - "selector": { 1135 - "description": "The start (or entire) text range.", 1136 - "allOf": [ 1137 - { 1138 - "$ref": "#/definitions/TextSelector" 1139 - } 1140 - ] 1141 - } 1142 - } 1143 - }, 1144 - "Time": { 1145 - "description": "A temporal range representing a starting time to an ending time.", 1146 - "type": "object", 1147 - "properties": { 1148 - "end": { 1149 - "description": "The end time or the end of the asset if not present.", 1150 - "type": [ 1151 - "string", 1152 - "null" 1153 - ] 1154 - }, 1155 - "start": { 1156 - "description": "The start time or the start of the asset if not present.", 1157 - "type": [ 1158 - "string", 1159 - "null" 1160 - ] 1161 - }, 1162 - "type": { 1163 - "description": "The type of time.", 1164 - "default": "npt", 1165 - "allOf": [ 1166 - { 1167 - "$ref": "#/definitions/TimeType" 1168 - } 1169 - ] 1170 - } 1171 - } 1172 - }, 1173 - "TimeType": { 1174 - "description": "The type of time.", 1175 - "oneOf": [ 1176 - { 1177 - "description": "Times are described using Normal Play Time (npt) as described in RFC 2326.", 1178 - "type": "string", 1179 - "enum": [ 1180 - "npt" 1181 - ] 1182 - } 1183 - ] 1184 - }, 1185 - "UnitType": { 1186 - "description": "The type of unit for the range.", 1187 - "oneOf": [ 1188 - { 1189 - "description": "Use pixels.", 1190 - "type": "string", 1191 - "enum": [ 1192 - "pixel" 1193 - ] 1194 - }, 1195 - { 1196 - "description": "Use percentage.", 1197 - "type": "string", 1198 - "enum": [ 1199 - "percent" 1200 - ] 1201 - } 1202 - ] 1203 - }, 1204 - "UriOrResource": { 1205 - "anyOf": [ 1206 - { 1207 - "$ref": "#/definitions/ResourceRef" 1208 - }, 1209 - { 1210 - "$ref": "#/definitions/HashedUri" 1211 - } 1212 - ] 1213 - }, 1214 - "ValidationResults": { 1215 - "description": "A map of validation results for a manifest store.\n\nThe map contains the validation results for the active manifest and any ingredient deltas. It is normal for there to be many", 1216 - "type": "object", 1217 - "properties": { 1218 - "activeManifest": { 1219 - "anyOf": [ 1220 - { 1221 - "$ref": "#/definitions/StatusCodes" 1222 - }, 1223 - { 1224 - "type": "null" 1225 - } 1226 - ] 1227 - }, 1228 - "ingredientDeltas": { 1229 - "type": [ 1230 - "array", 1231 - "null" 1232 - ], 1233 - "items": { 1234 - "$ref": "#/definitions/IngredientDeltaValidationResult" 1235 - } 1236 - } 1237 - } 1238 - }, 1239 - "ValidationStatus": { 1240 - "description": "A `ValidationStatus` struct describes the validation status of a specific part of a manifest.\n\nSee <https://c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_existing_manifests>.", 1241 - "type": "object", 1242 - "required": [ 1243 - "code" 1244 - ], 1245 - "properties": { 1246 - "code": { 1247 - "type": "string" 1248 - }, 1249 - "explanation": { 1250 - "type": [ 1251 - "string", 1252 - "null" 1253 - ] 1254 - }, 1255 - "success": { 1256 - "writeOnly": true, 1257 - "type": [ 1258 - "boolean", 1259 - "null" 1260 - ] 1261 - }, 1262 - "url": { 1263 - "type": [ 1264 - "string", 1265 - "null" 1266 - ] 1267 - } 1268 - } 1269 - } 1270 - } 1271 - }
+419 -461
pkg/c2pa/Reader.schema.json pkg/c2patypes/json/Everything.schema.json
··· 1 1 { 2 2 "$schema": "http://json-schema.org/draft-07/schema#", 3 - "title": "Reader", 4 - "description": "Use a Reader to read and validate a manifest store.", 3 + "title": "Everything", 5 4 "type": "object", 6 - "required": [ 7 - "manifests" 8 - ], 5 + "required": ["builder", "manifest_definition", "reader"], 9 6 "properties": { 10 - "active_manifest": { 11 - "description": "A label for the active (most recent) manifest in the store", 12 - "type": [ 13 - "string", 14 - "null" 15 - ] 7 + "builder": { 8 + "$ref": "#/definitions/Builder" 16 9 }, 17 - "manifests": { 18 - "description": "A HashMap of Manifests", 19 - "type": "object", 20 - "additionalProperties": { 21 - "$ref": "#/definitions/Manifest" 22 - } 10 + "manifest_definition": { 11 + "$ref": "#/definitions/ManifestDefinition" 23 12 }, 24 - "validation_results": { 25 - "description": "ValidationStatus generated when loading the ManifestStore from an asset", 26 - "anyOf": [ 27 - { 28 - "$ref": "#/definitions/ValidationResults" 29 - }, 30 - { 31 - "type": "null" 32 - } 33 - ] 34 - }, 35 - "validation_state": { 36 - "description": "The validation state of the manifest store", 37 - "anyOf": [ 38 - { 39 - "$ref": "#/definitions/ValidationState" 40 - }, 41 - { 42 - "type": "null" 43 - } 44 - ] 45 - }, 46 - "validation_status": { 47 - "description": "ValidationStatus generated when loading the ManifestStore from an asset", 48 - "type": [ 49 - "array", 50 - "null" 51 - ], 52 - "items": { 53 - "$ref": "#/definitions/ValidationStatus" 54 - } 13 + "reader": { 14 + "$ref": "#/definitions/Reader" 55 15 } 56 16 }, 57 17 "definitions": { ··· 61 21 "properties": { 62 22 "credentials": { 63 23 "description": "List of references to W3C Verifiable Credentials.", 64 - "type": [ 65 - "array", 66 - "null" 67 - ], 24 + "type": ["array", "null"], 68 25 "items": { 69 26 "$ref": "#/definitions/HashedUri" 70 27 } 71 28 }, 72 29 "identifier": { 73 30 "description": "An identifier for a human actor, used when the \"type\" is `humanEntry.identified`.", 74 - "type": [ 75 - "string", 76 - "null" 77 - ] 31 + "type": ["string", "null"] 32 + } 33 + } 34 + }, 35 + "AssertionData": { 36 + "description": "This allows the assertion to be expressed as CBOR or JSON. The default is CBOR unless you specify that an assertion should be JSON.", 37 + "anyOf": [true] 38 + }, 39 + "AssertionDefinition": { 40 + "description": "Defines an assertion that consists of a label that can be either a C2PA-defined assertion label or a custom label in reverse domain format.", 41 + "type": "object", 42 + "required": ["data", "label"], 43 + "properties": { 44 + "data": { 45 + "$ref": "#/definitions/AssertionData" 46 + }, 47 + "label": { 48 + "type": "string" 78 49 } 79 50 } 80 51 }, ··· 123 94 ] 124 95 }, 125 96 "reviewRatings": { 126 - "type": [ 127 - "array", 128 - "null" 129 - ], 97 + "type": ["array", "null"], 130 98 "items": { 131 99 "$ref": "#/definitions/ReviewRating" 132 100 } ··· 135 103 }, 136 104 "AssetType": { 137 105 "type": "object", 138 - "required": [ 139 - "type" 140 - ], 106 + "required": ["type"], 141 107 "properties": { 142 108 "type": { 143 109 "type": "string" 144 110 }, 145 111 "version": { 146 - "type": [ 147 - "string", 148 - "null" 112 + "type": ["string", "null"] 113 + } 114 + } 115 + }, 116 + "Builder": { 117 + "description": "Use a Builder to add a signed manifest to an asset.\n\n# Example: Building and signing a manifest\n\n``` use c2pa::Result; use std::path::PathBuf;\n\nuse c2pa::{create_signer, Builder, SigningAlg}; use serde::Serialize; use serde_json::json; use tempfile::tempdir;\n\n#[derive(Serialize)] struct Test { my_tag: usize, }\n\n# fn main() -> Result<()> { #[cfg(feature = \"file_io\")] { let manifest_json = json!({ \"claim_generator_info\": [ { \"name\": \"c2pa_test\", \"version\": \"1.0.0\" } ], \"title\": \"Test_Manifest\" }).to_string();\n\nlet mut builder = Builder::from_json(&manifest_json)?; builder.add_assertion(\"org.contentauth.test\", &Test { my_tag: 42 })?;\n\nlet source = PathBuf::from(\"tests/fixtures/C.jpg\"); let dir = tempdir()?; let dest = dir.path().join(\"test_file.jpg\");\n\n// Create a ps256 signer using certs and key files. TO DO: Update example. let signcert_path = \"tests/fixtures/certs/ps256.pub\"; let pkey_path = \"tests/fixtures/certs/ps256.pem\"; let signer = create_signer::from_files(signcert_path, pkey_path, SigningAlg::Ps256, None)?;\n\n// embed a manifest using the signer builder.sign_file( signer.as_ref(), &source, &dest)?; } # Ok(()) # } ```", 118 + "type": "object", 119 + "required": ["no_embed"], 120 + "properties": { 121 + "assertions": { 122 + "description": "A list of assertions", 123 + "default": [], 124 + "type": "array", 125 + "items": { 126 + "$ref": "#/definitions/AssertionDefinition" 127 + } 128 + }, 129 + "base_path": { 130 + "description": "Base path to search for resources.", 131 + "type": ["string", "null"] 132 + }, 133 + "builder_flow": { 134 + "description": "The type of builder being used.", 135 + "anyOf": [ 136 + { 137 + "$ref": "#/definitions/BuilderFlow" 138 + }, 139 + { 140 + "type": "null" 141 + } 149 142 ] 143 + }, 144 + "claim_generator_info": { 145 + "description": "Claim Generator Info is always required with at least one entry", 146 + "default": [ 147 + { 148 + "name": "c2pa-rs", 149 + "version": "0.58.0" 150 + } 151 + ], 152 + "type": "array", 153 + "items": { 154 + "$ref": "#/definitions/ClaimGeneratorInfo" 155 + } 156 + }, 157 + "claim_version": { 158 + "description": "The version of the claim. Defaults to 1.", 159 + "type": ["integer", "null"], 160 + "format": "uint8", 161 + "minimum": 0.0 162 + }, 163 + "format": { 164 + "description": "The format of the source file as a MIME type.", 165 + "default": "application/octet-stream", 166 + "type": "string" 167 + }, 168 + "ingredients": { 169 + "description": "A List of ingredients", 170 + "default": [], 171 + "type": "array", 172 + "items": { 173 + "$ref": "#/definitions/Ingredient" 174 + } 175 + }, 176 + "instance_id": { 177 + "description": "Instance ID from `xmpMM:InstanceID` in XMP metadata.", 178 + "default": "xmp:iid:ad854dd7-b8f6-46cf-93d5-9e0607131a38", 179 + "type": "string" 180 + }, 181 + "label": { 182 + "description": "Allows you to pre-define the manifest label, which must be unique. Not intended for general use. If not set, it will be assigned automatically.", 183 + "type": ["string", "null"] 184 + }, 185 + "metadata": { 186 + "description": "Optional manifest metadata. This will be deprecated in the future; not recommended to use.", 187 + "type": ["array", "null"], 188 + "items": { 189 + "$ref": "#/definitions/AssertionMetadata" 190 + } 191 + }, 192 + "no_embed": { 193 + "description": "If true, the manifest store will not be embedded in the asset on sign", 194 + "type": "boolean" 195 + }, 196 + "redactions": { 197 + "description": "A list of redactions - URIs to redacted assertions.", 198 + "type": ["array", "null"], 199 + "items": { 200 + "type": "string" 201 + } 202 + }, 203 + "remote_url": { 204 + "description": "Optional remote URL for the manifest", 205 + "type": ["string", "null"] 206 + }, 207 + "thumbnail": { 208 + "description": "An optional ResourceRef to a thumbnail image that represents the asset that was signed. Must be available when the manifest is signed.", 209 + "anyOf": [ 210 + { 211 + "$ref": "#/definitions/ResourceRef" 212 + }, 213 + { 214 + "type": "null" 215 + } 216 + ] 217 + }, 218 + "title": { 219 + "description": "A human-readable title, generally source filename.", 220 + "type": ["string", "null"] 221 + }, 222 + "vendor": { 223 + "description": "Optional prefix added to the generated Manifest Label This is typically a reverse domain name.", 224 + "type": ["string", "null"] 150 225 } 151 226 } 152 227 }, 228 + "BuilderFlow": { 229 + "description": "Represents the type of builder flow being used.\n\nThis determines how the builder will be used, such as creating a new asset, opening an existing asset, or updating an existing asset.", 230 + "oneOf": [ 231 + { 232 + "type": "string", 233 + "enum": ["Open", "Update"] 234 + }, 235 + { 236 + "type": "object", 237 + "required": ["Create"], 238 + "properties": { 239 + "Create": { 240 + "$ref": "#/definitions/DigitalSourceType" 241 + } 242 + }, 243 + "additionalProperties": false 244 + } 245 + ] 246 + }, 153 247 "ClaimGeneratorInfo": { 154 248 "description": "Description of the claim generator, or the software used in generating the claim.\n\nThis structure is also used for actions softwareAgent", 155 249 "type": "object", 156 - "required": [ 157 - "name" 158 - ], 250 + "required": ["name"], 159 251 "properties": { 160 252 "icon": { 161 253 "description": "hashed URI to the icon (either embedded or remote)", ··· 174 266 }, 175 267 "operating_system": { 176 268 "description": "A human readable string of the OS the claim generator is running on", 177 - "type": [ 178 - "string", 179 - "null" 180 - ] 269 + "type": ["string", "null"] 181 270 }, 182 271 "version": { 183 272 "description": "A human readable string of the product's version", 184 - "type": [ 185 - "string", 186 - "null" 187 - ] 273 + "type": ["string", "null"] 188 274 } 189 275 }, 190 276 "additionalProperties": true ··· 192 278 "Coordinate": { 193 279 "description": "An x, y coordinate used for specifying vertices in polygons.", 194 280 "type": "object", 195 - "required": [ 196 - "x", 197 - "y" 198 - ], 281 + "required": ["x", "y"], 199 282 "properties": { 200 283 "x": { 201 284 "description": "The coordinate along the x-axis.", ··· 212 295 "DataSource": { 213 296 "description": "A description of the source for assertion data", 214 297 "type": "object", 215 - "required": [ 216 - "type" 217 - ], 298 + "required": ["type"], 218 299 "properties": { 219 300 "actors": { 220 301 "description": "A list of [`Actor`]s associated with this source.", 221 - "type": [ 222 - "array", 223 - "null" 224 - ], 302 + "type": ["array", "null"], 225 303 "items": { 226 304 "$ref": "#/definitions/Actor" 227 305 } 228 306 }, 229 307 "details": { 230 308 "description": "A human-readable string giving details about the source of the assertion data.", 231 - "type": [ 232 - "string", 233 - "null" 234 - ] 309 + "type": ["string", "null"] 235 310 }, 236 311 "type": { 237 312 "description": "A value from among the enumerated list indicating the source of the assertion.", ··· 242 317 "DateT": { 243 318 "type": "string" 244 319 }, 320 + "DigitalSourceType": { 321 + "oneOf": [ 322 + { 323 + "description": "Media whose digital content is effectively empty, such as a blank canvas or zero-length video.", 324 + "type": "string", 325 + "enum": ["Empty"] 326 + }, 327 + { 328 + "description": "Data that is the result of algorithmically using a model derived from sampled content and data. Differs from <http://cv.iptc.org/newscodes/digitalsourcetype/>trainedAlgorithmicMedia in that the result isn’t a media type (e.g., image or video) but is a data format (e.g., CSV, pickle).", 329 + "type": "string", 330 + "enum": ["TrainedAlgorithmicData"] 331 + } 332 + ] 333 + }, 245 334 "Frame": { 246 335 "description": "A frame range representing starting and ending frames or pages.\n\nIf both `start` and `end` are missing, the frame will span the entire asset.", 247 336 "type": "object", 248 337 "properties": { 249 338 "end": { 250 339 "description": "The end of the frame inclusive or the end of the asset if not present.", 251 - "type": [ 252 - "integer", 253 - "null" 254 - ], 340 + "type": ["integer", "null"], 255 341 "format": "int32" 256 342 }, 257 343 "start": { 258 344 "description": "The start of the frame or the end of the asset if not present.\n\nThe first frame/page starts at 0.", 259 - "type": [ 260 - "integer", 261 - "null" 262 - ], 345 + "type": ["integer", "null"], 263 346 "format": "int32" 264 347 } 265 348 } ··· 267 350 "HashedUri": { 268 351 "description": "A `HashedUri` provides a reference to content available within the same manifest store.\n\nThis is described in [§8.3, URI References], of the C2PA Technical Specification.\n\n[§8.3, URI References]: https://c2pa.org/specifications/specifications/2.1/specs/C2PA_Specification.html#_uri_references", 269 352 "type": "object", 270 - "required": [ 271 - "hash", 272 - "url" 273 - ], 353 + "required": ["hash", "url"], 274 354 "properties": { 275 355 "alg": { 276 356 "description": "A string identifying the cryptographic hash algorithm used to compute the hash", 277 - "type": [ 278 - "string", 279 - "null" 280 - ] 357 + "type": ["string", "null"] 281 358 }, 282 359 "hash": { 283 360 "description": "Byte string containing the hash value", ··· 300 377 "properties": { 301 378 "active_manifest": { 302 379 "description": "The active manifest label (if one exists).\n\nIf this ingredient has a [`ManifestStore`], this will hold the label of the active [`Manifest`].\n\n[`Manifest`]: crate::Manifest [`ManifestStore`]: crate::ManifestStore", 303 - "type": [ 304 - "string", 305 - "null" 306 - ] 380 + "type": ["string", "null"] 307 381 }, 308 382 "data": { 309 383 "description": "A reference to the actual data of the ingredient.", ··· 318 392 }, 319 393 "data_types": { 320 394 "description": "Additional information about the data's type to the ingredient V2 structure.", 321 - "type": [ 322 - "array", 323 - "null" 324 - ], 395 + "type": ["array", "null"], 325 396 "items": { 326 397 "$ref": "#/definitions/AssetType" 327 398 } 328 399 }, 329 400 "description": { 330 401 "description": "Additional description of the ingredient.", 331 - "type": [ 332 - "string", 333 - "null" 334 - ] 402 + "type": ["string", "null"] 335 403 }, 336 404 "document_id": { 337 405 "description": "Document ID from `xmpMM:DocumentID` in XMP metadata.", 338 - "type": [ 339 - "string", 340 - "null" 341 - ] 406 + "type": ["string", "null"] 342 407 }, 343 408 "format": { 344 409 "description": "The format of the source file as a MIME type.", 345 - "type": [ 346 - "string", 347 - "null" 348 - ] 410 + "type": ["string", "null"] 349 411 }, 350 412 "hash": { 351 413 "description": "An optional hash of the asset to prevent duplicates.", 352 - "type": [ 353 - "string", 354 - "null" 355 - ] 414 + "type": ["string", "null"] 356 415 }, 357 416 "informational_URI": { 358 417 "description": "URI to an informational page about the ingredient or its data.", 359 - "type": [ 360 - "string", 361 - "null" 362 - ] 418 + "type": ["string", "null"] 363 419 }, 364 420 "instance_id": { 365 421 "description": "Instance ID from `xmpMM:InstanceID` in XMP metadata.", 366 - "type": [ 367 - "string", 368 - "null" 369 - ] 422 + "type": ["string", "null"] 370 423 }, 371 424 "label": { 372 425 "description": "The ingredient's label as assigned in the manifest.", 373 - "type": [ 374 - "string", 375 - "null" 376 - ] 426 + "type": ["string", "null"] 377 427 }, 378 428 "manifest_data": { 379 429 "description": "A [`ManifestStore`] from the source asset extracted as a binary C2PA blob.\n\n[`ManifestStore`]: crate::ManifestStore", ··· 399 449 }, 400 450 "provenance": { 401 451 "description": "URI from `dcterms:provenance` in XMP metadata.", 402 - "type": [ 403 - "string", 404 - "null" 405 - ] 452 + "type": ["string", "null"] 406 453 }, 407 454 "relationship": { 408 455 "description": "Set to `ParentOf` if this is the parent ingredient.\n\nThere can only be one parent ingredient in the ingredients.", ··· 434 481 }, 435 482 "title": { 436 483 "description": "A human-readable title, generally source filename.", 437 - "type": [ 438 - "string", 439 - "null" 440 - ] 484 + "type": ["string", "null"] 441 485 }, 442 486 "validation_results": { 443 487 "description": "Validation results (Ingredient.V3)", ··· 452 496 }, 453 497 "validation_status": { 454 498 "description": "Validation status (Ingredient v1 & v2)", 455 - "type": [ 456 - "array", 457 - "null" 458 - ], 499 + "type": ["array", "null"], 459 500 "items": { 460 501 "$ref": "#/definitions/ValidationStatus" 461 502 } ··· 465 506 "IngredientDeltaValidationResult": { 466 507 "description": "Represents any changes or deltas between the current and previous validation results for an ingredient's manifest.", 467 508 "type": "object", 468 - "required": [ 469 - "ingredientAssertionURI", 470 - "validationDeltas" 471 - ], 509 + "required": ["ingredientAssertionURI", "validationDeltas"], 472 510 "properties": { 473 511 "ingredientAssertionURI": { 474 512 "description": "JUMBF URI reference to the ingredient assertion", ··· 487 525 "Item": { 488 526 "description": "Description of the boundaries of an identified range.", 489 527 "type": "object", 490 - "required": [ 491 - "identifier", 492 - "value" 493 - ], 528 + "required": ["identifier", "value"], 494 529 "properties": { 495 530 "identifier": { 496 531 "description": "The container-specific term used to identify items, such as \"track_id\" for MP4 or \"item_ID\" for HEIF.", ··· 516 551 }, 517 552 "claim_generator": { 518 553 "description": "A User Agent formatted string identifying the software/hardware/system produced this claim Spaces are not allowed in names, versions can be specified with product/1.0 syntax.", 519 - "type": [ 520 - "string", 521 - "null" 522 - ] 554 + "type": ["string", "null"] 523 555 }, 524 556 "claim_generator_info": { 525 557 "description": "A list of claim generator info data identifying the software/hardware/system produced this claim.", 526 - "type": [ 527 - "array", 528 - "null" 529 - ], 558 + "type": ["array", "null"], 530 559 "items": { 531 560 "$ref": "#/definitions/ClaimGeneratorInfo" 532 561 } 533 562 }, 534 563 "credentials": { 535 564 "description": "A List of verified credentials", 536 - "type": [ 537 - "array", 538 - "null" 539 - ], 565 + "type": ["array", "null"], 540 566 "items": true 541 567 }, 542 568 "format": { 543 569 "description": "The format of the source file as a MIME type.", 544 - "type": [ 545 - "string", 546 - "null" 547 - ] 570 + "type": ["string", "null"] 548 571 }, 549 572 "ingredients": { 550 573 "description": "A List of ingredients", ··· 556 579 }, 557 580 "instance_id": { 558 581 "description": "Instance ID from `xmpMM:InstanceID` in XMP metadata.", 559 - "default": "xmp:iid:855e296c-2f54-4a0a-ae5a-0659b3bca8b8", 582 + "default": "xmp:iid:162c4576-2f5c-4852-93ad-e15b784e19e8", 560 583 "type": "string" 561 584 }, 562 585 "label": { 563 - "type": [ 564 - "string", 565 - "null" 566 - ] 586 + "type": ["string", "null"] 567 587 }, 568 588 "metadata": { 569 589 "description": "A list of user metadata for this claim.", 570 - "type": [ 571 - "array", 572 - "null" 573 - ], 590 + "type": ["array", "null"], 574 591 "items": { 575 592 "$ref": "#/definitions/AssertionMetadata" 576 593 } 577 594 }, 578 595 "redactions": { 579 596 "description": "A list of redactions - URIs to a redacted assertions", 580 - "type": [ 581 - "array", 582 - "null" 583 - ], 597 + "type": ["array", "null"], 584 598 "items": { 585 599 "type": "string" 586 600 } ··· 617 631 }, 618 632 "title": { 619 633 "description": "A human-readable title, generally source filename.", 620 - "type": [ 621 - "string", 622 - "null" 623 - ] 634 + "type": ["string", "null"] 624 635 }, 625 636 "vendor": { 626 637 "description": "Optional prefix added to the generated Manifest label. This is typically an internet domain name for the vendor (i.e. `adobe`).", 627 - "type": [ 628 - "string", 629 - "null" 630 - ] 638 + "type": ["string", "null"] 631 639 } 632 640 } 633 641 }, 634 642 "ManifestAssertion": { 635 643 "description": "A labeled container for an Assertion value in a Manifest", 636 644 "type": "object", 637 - "required": [ 638 - "data", 639 - "label" 640 - ], 645 + "required": ["data", "label"], 641 646 "properties": { 642 647 "data": { 643 648 "description": "The data of the assertion as Value", ··· 649 654 }, 650 655 "instance": { 651 656 "description": "There can be more than one assertion for any label", 652 - "type": [ 653 - "integer", 654 - "null" 655 - ], 657 + "type": ["integer", "null"], 656 658 "format": "uint", 657 659 "minimum": 0.0 658 660 }, ··· 676 678 "ManifestAssertionKind": { 677 679 "description": "Assertions in C2PA can be stored in several formats", 678 680 "type": "string", 679 - "enum": [ 680 - "Cbor", 681 - "Json", 682 - "Binary", 683 - "Uri" 684 - ] 681 + "enum": ["Cbor", "Json", "Binary", "Uri"] 685 682 }, 686 683 "ManifestData": { 687 684 "anyOf": [ ··· 696 693 } 697 694 ] 698 695 }, 696 + "ManifestDefinition": { 697 + "description": "Use a ManifestDefinition to define a manifest and to build a `ManifestStore`. A manifest is a collection of ingredients and assertions used to define a claim that can be signed and embedded into a file.", 698 + "type": "object", 699 + "properties": { 700 + "assertions": { 701 + "description": "A list of assertions", 702 + "default": [], 703 + "type": "array", 704 + "items": { 705 + "$ref": "#/definitions/AssertionDefinition" 706 + } 707 + }, 708 + "claim_generator_info": { 709 + "description": "Claim Generator Info is always required with at least one entry", 710 + "default": [ 711 + { 712 + "name": "c2pa-rs", 713 + "version": "0.58.0" 714 + } 715 + ], 716 + "type": "array", 717 + "items": { 718 + "$ref": "#/definitions/ClaimGeneratorInfo" 719 + } 720 + }, 721 + "claim_version": { 722 + "description": "The version of the claim. Defaults to 1.", 723 + "type": ["integer", "null"], 724 + "format": "uint8", 725 + "minimum": 0.0 726 + }, 727 + "format": { 728 + "description": "The format of the source file as a MIME type.", 729 + "default": "application/octet-stream", 730 + "type": "string" 731 + }, 732 + "ingredients": { 733 + "description": "A List of ingredients", 734 + "default": [], 735 + "type": "array", 736 + "items": { 737 + "$ref": "#/definitions/Ingredient" 738 + } 739 + }, 740 + "instance_id": { 741 + "description": "Instance ID from `xmpMM:InstanceID` in XMP metadata.", 742 + "default": "xmp:iid:39745b0f-82b0-4848-b2ac-695b1acd4893", 743 + "type": "string" 744 + }, 745 + "label": { 746 + "description": "Allows you to pre-define the manifest label, which must be unique. Not intended for general use. If not set, it will be assigned automatically.", 747 + "type": ["string", "null"] 748 + }, 749 + "metadata": { 750 + "description": "Optional manifest metadata. This will be deprecated in the future; not recommended to use.", 751 + "type": ["array", "null"], 752 + "items": { 753 + "$ref": "#/definitions/AssertionMetadata" 754 + } 755 + }, 756 + "redactions": { 757 + "description": "A list of redactions - URIs to redacted assertions.", 758 + "type": ["array", "null"], 759 + "items": { 760 + "type": "string" 761 + } 762 + }, 763 + "thumbnail": { 764 + "description": "An optional ResourceRef to a thumbnail image that represents the asset that was signed. Must be available when the manifest is signed.", 765 + "anyOf": [ 766 + { 767 + "$ref": "#/definitions/ResourceRef" 768 + }, 769 + { 770 + "type": "null" 771 + } 772 + ] 773 + }, 774 + "title": { 775 + "description": "A human-readable title, generally source filename.", 776 + "type": ["string", "null"] 777 + }, 778 + "vendor": { 779 + "description": "Optional prefix added to the generated Manifest Label This is typically a reverse domain name.", 780 + "type": ["string", "null"] 781 + } 782 + } 783 + }, 699 784 "Range": { 700 785 "description": "A spatial, temporal, frame, or textual range describing the region of interest.", 701 786 "type": "object", 702 - "required": [ 703 - "type" 704 - ], 787 + "required": ["type"], 705 788 "properties": { 706 789 "frame": { 707 790 "description": "A frame range.", ··· 774 857 { 775 858 "description": "A spatial range, see [`Shape`] for more details.", 776 859 "type": "string", 777 - "enum": [ 778 - "spatial" 779 - ] 860 + "enum": ["spatial"] 780 861 }, 781 862 { 782 863 "description": "A temporal range, see [`Time`] for more details.", 783 864 "type": "string", 784 - "enum": [ 785 - "temporal" 786 - ] 865 + "enum": ["temporal"] 787 866 }, 788 867 { 789 868 "description": "A spatial range, see [`Frame`] for more details.", 790 869 "type": "string", 791 - "enum": [ 792 - "frame" 793 - ] 870 + "enum": ["frame"] 794 871 }, 795 872 { 796 873 "description": "A textual range, see [`Text`] for more details.", 797 874 "type": "string", 798 - "enum": [ 799 - "textual" 800 - ] 875 + "enum": ["textual"] 801 876 }, 802 877 { 803 878 "description": "A range identified by a specific identifier and value, see [`Item`] for more details.", 804 879 "type": "string", 805 - "enum": [ 806 - "identified" 807 - ] 880 + "enum": ["identified"] 808 881 } 809 882 ] 810 883 }, 884 + "Reader": { 885 + "description": "Use a Reader to read and validate a manifest store.", 886 + "type": "object", 887 + "required": ["manifests"], 888 + "properties": { 889 + "active_manifest": { 890 + "description": "A label for the active (most recent) manifest in the store", 891 + "type": ["string", "null"] 892 + }, 893 + "manifests": { 894 + "description": "A HashMap of Manifests", 895 + "type": "object", 896 + "additionalProperties": { 897 + "$ref": "#/definitions/Manifest" 898 + } 899 + }, 900 + "validation_results": { 901 + "description": "ValidationStatus generated when loading the ManifestStore from an asset", 902 + "anyOf": [ 903 + { 904 + "$ref": "#/definitions/ValidationResults" 905 + }, 906 + { 907 + "type": "null" 908 + } 909 + ] 910 + }, 911 + "validation_state": { 912 + "description": "The validation state of the manifest store", 913 + "anyOf": [ 914 + { 915 + "$ref": "#/definitions/ValidationState" 916 + }, 917 + { 918 + "type": "null" 919 + } 920 + ] 921 + }, 922 + "validation_status": { 923 + "description": "ValidationStatus generated when loading the ManifestStore from an asset", 924 + "type": ["array", "null"], 925 + "items": { 926 + "$ref": "#/definitions/ValidationStatus" 927 + } 928 + } 929 + } 930 + }, 811 931 "RegionOfInterest": { 812 932 "description": "A region of interest within an asset describing the change.\n\nThis struct can be used from [`Action::changes`][crate::assertions::Action::changes] or [`AssertionMetadata::region_of_interest`][crate::assertions::AssertionMetadata::region_of_interest].", 813 933 "type": "object", 814 - "required": [ 815 - "region" 816 - ], 934 + "required": ["region"], 817 935 "properties": { 818 936 "description": { 819 937 "description": "A free-text string.", 820 - "type": [ 821 - "string", 822 - "null" 823 - ] 938 + "type": ["string", "null"] 824 939 }, 825 940 "identifier": { 826 941 "description": "A free-text string representing a machine-readable, unique to this assertion, identifier for the region.", 827 - "type": [ 828 - "string", 829 - "null" 830 - ] 942 + "type": ["string", "null"] 831 943 }, 832 944 "metadata": { 833 945 "description": "Additional information about the asset.", ··· 842 954 }, 843 955 "name": { 844 956 "description": "A free-text string representing a human-readable name for the region which might be used in a user interface.", 845 - "type": [ 846 - "string", 847 - "null" 848 - ] 957 + "type": ["string", "null"] 849 958 }, 850 959 "region": { 851 960 "description": "A range describing the region of interest for the specific asset.", ··· 867 976 }, 868 977 "type": { 869 978 "description": "A value from a controlled vocabulary such as <https://cv.iptc.org/newscodes/imageregiontype/> or an entity-specific value (e.g., com.litware.newType) that represents the type of thing(s) depicted by a region.\n\nNote this field serializes/deserializes into the name `type`.", 870 - "type": [ 871 - "string", 872 - "null" 873 - ] 979 + "type": ["string", "null"] 874 980 } 875 981 } 876 982 }, ··· 880 986 { 881 987 "description": "The current asset is derived from this ingredient.", 882 988 "type": "string", 883 - "enum": [ 884 - "parentOf" 885 - ] 989 + "enum": ["parentOf"] 886 990 }, 887 991 { 888 992 "description": "The current asset is a part of this ingredient.", 889 993 "type": "string", 890 - "enum": [ 891 - "componentOf" 892 - ] 994 + "enum": ["componentOf"] 893 995 }, 894 996 { 895 997 "description": "The ingredient was used as an input to a computational process to create or modify the asset.", 896 998 "type": "string", 897 - "enum": [ 898 - "inputTo" 899 - ] 999 + "enum": ["inputTo"] 900 1000 } 901 1001 ] 902 1002 }, 903 1003 "ResourceRef": { 904 1004 "description": "A reference to a resource to be used in JSON serialization.\n\nThe underlying data can be read as a stream via [`Reader::resource_to_stream`][crate::Reader::resource_to_stream].", 905 1005 "type": "object", 906 - "required": [ 907 - "format", 908 - "identifier" 909 - ], 1006 + "required": ["format", "identifier"], 910 1007 "properties": { 911 1008 "alg": { 912 1009 "description": "The algorithm used to hash the resource (if applicable).", 913 - "type": [ 914 - "string", 915 - "null" 916 - ] 1010 + "type": ["string", "null"] 917 1011 }, 918 1012 "data_types": { 919 1013 "description": "More detailed data types as defined in the C2PA spec.", 920 - "type": [ 921 - "array", 922 - "null" 923 - ], 1014 + "type": ["array", "null"], 924 1015 "items": { 925 1016 "$ref": "#/definitions/AssetType" 926 1017 } ··· 931 1022 }, 932 1023 "hash": { 933 1024 "description": "The hash of the resource (if applicable).", 934 - "type": [ 935 - "string", 936 - "null" 937 - ] 1025 + "type": ["string", "null"] 938 1026 }, 939 1027 "identifier": { 940 1028 "description": "A URI that identifies the resource as referenced from the manifest.\n\nThis may be a JUMBF URI, a file path, a URL or any other string. Relative JUMBF URIs will be resolved with the manifest label. Relative file paths will be resolved with the base path if provided.", ··· 945 1033 "ResourceStore": { 946 1034 "description": "Resource store to contain binary objects referenced from JSON serializable structures", 947 1035 "type": "object", 948 - "required": [ 949 - "resources" 950 - ], 1036 + "required": ["resources"], 951 1037 "properties": { 952 1038 "base_path": { 953 - "type": [ 954 - "string", 955 - "null" 956 - ] 1039 + "type": ["string", "null"] 957 1040 }, 958 1041 "label": { 959 - "type": [ 960 - "string", 961 - "null" 962 - ] 1042 + "type": ["string", "null"] 963 1043 }, 964 1044 "resources": { 965 1045 "type": "object", ··· 977 1057 "ReviewRating": { 978 1058 "description": "A rating on an Assertion.\n\nSee <https://c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_review_ratings>.", 979 1059 "type": "object", 980 - "required": [ 981 - "explanation", 982 - "value" 983 - ], 1060 + "required": ["explanation", "value"], 984 1061 "properties": { 985 1062 "code": { 986 - "type": [ 987 - "string", 988 - "null" 989 - ] 1063 + "type": ["string", "null"] 990 1064 }, 991 1065 "explanation": { 992 1066 "type": "string" ··· 1004 1078 { 1005 1079 "description": "Arbitrary area worth identifying.", 1006 1080 "type": "string", 1007 - "enum": [ 1008 - "c2pa.areaOfInterest" 1009 - ] 1081 + "enum": ["c2pa.areaOfInterest"] 1010 1082 }, 1011 1083 { 1012 1084 "description": "This area is all that is left after a crop action.", 1013 1085 "type": "string", 1014 - "enum": [ 1015 - "c2pa.cropped" 1016 - ] 1086 + "enum": ["c2pa.cropped"] 1017 1087 }, 1018 1088 { 1019 1089 "description": "This area has had edits applied to it.", 1020 1090 "type": "string", 1021 - "enum": [ 1022 - "c2pa.edited" 1023 - ] 1091 + "enum": ["c2pa.edited"] 1024 1092 }, 1025 1093 { 1026 1094 "description": "The area where an ingredient was placed/added.", 1027 1095 "type": "string", 1028 - "enum": [ 1029 - "c2pa.placed" 1030 - ] 1096 + "enum": ["c2pa.placed"] 1031 1097 }, 1032 1098 { 1033 1099 "description": "Something in this area was redacted.", 1034 1100 "type": "string", 1035 - "enum": [ 1036 - "c2pa.redacted" 1037 - ] 1101 + "enum": ["c2pa.redacted"] 1038 1102 }, 1039 1103 { 1040 1104 "description": "Area specific to a subject (human or not).", 1041 1105 "type": "string", 1042 - "enum": [ 1043 - "c2pa.subjectArea" 1044 - ] 1106 + "enum": ["c2pa.subjectArea"] 1045 1107 }, 1046 1108 { 1047 1109 "description": "A range of information was removed/deleted.", 1048 1110 "type": "string", 1049 - "enum": [ 1050 - "c2pa.deleted" 1051 - ] 1111 + "enum": ["c2pa.deleted"] 1052 1112 }, 1053 1113 { 1054 1114 "description": "Styling was applied to this area.", 1055 1115 "type": "string", 1056 - "enum": [ 1057 - "c2pa.styled" 1058 - ] 1116 + "enum": ["c2pa.styled"] 1059 1117 }, 1060 1118 { 1061 1119 "description": "Invisible watermarking was applied to this area for the purpose of soft binding.", 1062 1120 "type": "string", 1063 - "enum": [ 1064 - "c2pa.watermarked" 1065 - ] 1121 + "enum": ["c2pa.watermarked"] 1066 1122 } 1067 1123 ] 1068 1124 }, 1069 1125 "Shape": { 1070 1126 "description": "A spatial range representing rectangle, circle, or a polygon.", 1071 1127 "type": "object", 1072 - "required": [ 1073 - "origin", 1074 - "type", 1075 - "unit" 1076 - ], 1128 + "required": ["origin", "type", "unit"], 1077 1129 "properties": { 1078 1130 "height": { 1079 1131 "description": "The height of a rectnagle.\n\nThis field can be ignored for circles and polygons.", 1080 - "type": [ 1081 - "number", 1082 - "null" 1083 - ], 1132 + "type": ["number", "null"], 1084 1133 "format": "double" 1085 1134 }, 1086 1135 "inside": { 1087 1136 "description": "If the range is inside the shape.\n\nThe default value is true.", 1088 - "type": [ 1089 - "boolean", 1090 - "null" 1091 - ] 1137 + "type": ["boolean", "null"] 1092 1138 }, 1093 1139 "origin": { 1094 1140 "description": "THe origin of the coordinate in the shape.", ··· 1116 1162 }, 1117 1163 "vertices": { 1118 1164 "description": "The vertices of the polygon.\n\nThis field can be ignored for rectangles and circles.", 1119 - "type": [ 1120 - "array", 1121 - "null" 1122 - ], 1165 + "type": ["array", "null"], 1123 1166 "items": { 1124 1167 "$ref": "#/definitions/Coordinate" 1125 1168 } 1126 1169 }, 1127 1170 "width": { 1128 1171 "description": "The width for rectangles or diameter for circles.\n\nThis field can be ignored for polygons.", 1129 - "type": [ 1130 - "number", 1131 - "null" 1132 - ], 1172 + "type": ["number", "null"], 1133 1173 "format": "double" 1134 1174 } 1135 1175 } ··· 1140 1180 { 1141 1181 "description": "A rectangle.", 1142 1182 "type": "string", 1143 - "enum": [ 1144 - "rectangle" 1145 - ] 1183 + "enum": ["rectangle"] 1146 1184 }, 1147 1185 { 1148 1186 "description": "A circle.", 1149 1187 "type": "string", 1150 - "enum": [ 1151 - "circle" 1152 - ] 1188 + "enum": ["circle"] 1153 1189 }, 1154 1190 { 1155 1191 "description": "A polygon.", 1156 1192 "type": "string", 1157 - "enum": [ 1158 - "polygon" 1159 - ] 1193 + "enum": ["polygon"] 1160 1194 } 1161 1195 ] 1162 1196 }, ··· 1177 1211 }, 1178 1212 "cert_serial_number": { 1179 1213 "description": "The serial number of the certificate.", 1180 - "type": [ 1181 - "string", 1182 - "null" 1183 - ] 1214 + "type": ["string", "null"] 1184 1215 }, 1185 1216 "issuer": { 1186 1217 "description": "Human-readable issuing authority for this signature.", 1187 - "type": [ 1188 - "string", 1189 - "null" 1190 - ] 1218 + "type": ["string", "null"] 1191 1219 }, 1192 1220 "revocation_status": { 1193 1221 "description": "Revocation status of the certificate.", 1194 - "type": [ 1195 - "boolean", 1196 - "null" 1197 - ] 1222 + "type": ["boolean", "null"] 1198 1223 }, 1199 1224 "time": { 1200 1225 "description": "The time the signature was created.", 1201 - "type": [ 1202 - "string", 1203 - "null" 1204 - ] 1226 + "type": ["string", "null"] 1205 1227 } 1206 1228 } 1207 1229 }, ··· 1211 1233 { 1212 1234 "description": "ECDSA with SHA-256", 1213 1235 "type": "string", 1214 - "enum": [ 1215 - "Es256" 1216 - ] 1236 + "enum": ["Es256"] 1217 1237 }, 1218 1238 { 1219 1239 "description": "ECDSA with SHA-256 on secp256k1 curve", 1220 1240 "type": "string", 1221 - "enum": [ 1222 - "Es256K" 1223 - ] 1241 + "enum": ["Es256K"] 1224 1242 }, 1225 1243 { 1226 1244 "description": "ECDSA with SHA-384", 1227 1245 "type": "string", 1228 - "enum": [ 1229 - "Es384" 1230 - ] 1246 + "enum": ["Es384"] 1231 1247 }, 1232 1248 { 1233 1249 "description": "ECDSA with SHA-512", 1234 1250 "type": "string", 1235 - "enum": [ 1236 - "Es512" 1237 - ] 1251 + "enum": ["Es512"] 1238 1252 }, 1239 1253 { 1240 1254 "description": "RSASSA-PSS using SHA-256 and MGF1 with SHA-256", 1241 1255 "type": "string", 1242 - "enum": [ 1243 - "Ps256" 1244 - ] 1256 + "enum": ["Ps256"] 1245 1257 }, 1246 1258 { 1247 1259 "description": "RSASSA-PSS using SHA-384 and MGF1 with SHA-384", 1248 1260 "type": "string", 1249 - "enum": [ 1250 - "Ps384" 1251 - ] 1261 + "enum": ["Ps384"] 1252 1262 }, 1253 1263 { 1254 1264 "description": "RSASSA-PSS using SHA-512 and MGF1 with SHA-512", 1255 1265 "type": "string", 1256 - "enum": [ 1257 - "Ps512" 1258 - ] 1266 + "enum": ["Ps512"] 1259 1267 }, 1260 1268 { 1261 1269 "description": "Edwards-Curve DSA (Ed25519 instance only)", 1262 1270 "type": "string", 1263 - "enum": [ 1264 - "Ed25519" 1265 - ] 1271 + "enum": ["Ed25519"] 1266 1272 } 1267 1273 ] 1268 1274 }, 1269 1275 "StatusCodes": { 1270 1276 "description": "Contains a set of success, informational, and failure validation status codes.", 1271 1277 "type": "object", 1272 - "required": [ 1273 - "failure", 1274 - "informational", 1275 - "success" 1276 - ], 1278 + "required": ["failure", "informational", "success"], 1277 1279 "properties": { 1278 1280 "failure": { 1279 1281 "type": "array", ··· 1298 1300 "Text": { 1299 1301 "description": "A textual range representing multiple (possibly discontinuous) ranges of text.", 1300 1302 "type": "object", 1301 - "required": [ 1302 - "selectors" 1303 - ], 1303 + "required": ["selectors"], 1304 1304 "properties": { 1305 1305 "selectors": { 1306 1306 "description": "The ranges of text to select.", ··· 1314 1314 "TextSelector": { 1315 1315 "description": "Selects a range of text via a fragment identifier.\n\nThis is modeled after the W3C Web Annotation selector model.", 1316 1316 "type": "object", 1317 - "required": [ 1318 - "fragment" 1319 - ], 1317 + "required": ["fragment"], 1320 1318 "properties": { 1321 1319 "end": { 1322 1320 "description": "The end character offset or the end of the fragment if not present.", 1323 - "type": [ 1324 - "integer", 1325 - "null" 1326 - ], 1321 + "type": ["integer", "null"], 1327 1322 "format": "int32" 1328 1323 }, 1329 1324 "fragment": { ··· 1332 1327 }, 1333 1328 "start": { 1334 1329 "description": "The start character offset or the start of the fragment if not present.", 1335 - "type": [ 1336 - "integer", 1337 - "null" 1338 - ], 1330 + "type": ["integer", "null"], 1339 1331 "format": "int32" 1340 1332 } 1341 1333 } ··· 1343 1335 "TextSelectorRange": { 1344 1336 "description": "One or two [`TextSelector`][TextSelector] identifiying the range to select.", 1345 1337 "type": "object", 1346 - "required": [ 1347 - "selector" 1348 - ], 1338 + "required": ["selector"], 1349 1339 "properties": { 1350 1340 "end": { 1351 1341 "description": "The end of the text range.", ··· 1374 1364 "properties": { 1375 1365 "end": { 1376 1366 "description": "The end time or the end of the asset if not present.", 1377 - "type": [ 1378 - "string", 1379 - "null" 1380 - ] 1367 + "type": ["string", "null"] 1381 1368 }, 1382 1369 "start": { 1383 1370 "description": "The start time or the start of the asset if not present.", 1384 - "type": [ 1385 - "string", 1386 - "null" 1387 - ] 1371 + "type": ["string", "null"] 1388 1372 }, 1389 1373 "type": { 1390 1374 "description": "The type of time.", ··· 1403 1387 { 1404 1388 "description": "Times are described using Normal Play Time (npt) as described in RFC 2326.", 1405 1389 "type": "string", 1406 - "enum": [ 1407 - "npt" 1408 - ] 1390 + "enum": ["npt"] 1409 1391 } 1410 1392 ] 1411 1393 }, ··· 1415 1397 { 1416 1398 "description": "Use pixels.", 1417 1399 "type": "string", 1418 - "enum": [ 1419 - "pixel" 1420 - ] 1400 + "enum": ["pixel"] 1421 1401 }, 1422 1402 { 1423 1403 "description": "Use percentage.", 1424 1404 "type": "string", 1425 - "enum": [ 1426 - "percent" 1427 - ] 1405 + "enum": ["percent"] 1428 1406 } 1429 1407 ] 1430 1408 }, ··· 1453 1431 ] 1454 1432 }, 1455 1433 "ingredientDeltas": { 1456 - "type": [ 1457 - "array", 1458 - "null" 1459 - ], 1434 + "type": ["array", "null"], 1460 1435 "items": { 1461 1436 "$ref": "#/definitions/IngredientDeltaValidationResult" 1462 1437 } ··· 1469 1444 { 1470 1445 "description": "Errors were found in the manifest store.", 1471 1446 "type": "string", 1472 - "enum": [ 1473 - "Invalid" 1474 - ] 1447 + "enum": ["Invalid"] 1475 1448 }, 1476 1449 { 1477 1450 "description": "No errors were found in validation, but the active signature is not trusted.", 1478 1451 "type": "string", 1479 - "enum": [ 1480 - "Valid" 1481 - ] 1452 + "enum": ["Valid"] 1482 1453 }, 1483 1454 { 1484 1455 "description": "The manifest store is valid and the active signature is trusted.", 1485 1456 "type": "string", 1486 - "enum": [ 1487 - "Trusted" 1488 - ] 1457 + "enum": ["Trusted"] 1489 1458 } 1490 1459 ] 1491 1460 }, 1492 1461 "ValidationStatus": { 1493 1462 "description": "A `ValidationStatus` struct describes the validation status of a specific part of a manifest.\n\nSee <https://c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_existing_manifests>.", 1494 1463 "type": "object", 1495 - "required": [ 1496 - "code" 1497 - ], 1464 + "required": ["code"], 1498 1465 "properties": { 1499 1466 "code": { 1500 1467 "type": "string" 1501 1468 }, 1502 1469 "explanation": { 1503 - "type": [ 1504 - "string", 1505 - "null" 1506 - ] 1470 + "type": ["string", "null"] 1507 1471 }, 1508 1472 "success": { 1509 1473 "writeOnly": true, 1510 - "type": [ 1511 - "boolean", 1512 - "null" 1513 - ] 1474 + "type": ["boolean", "null"] 1514 1475 }, 1515 1476 "url": { 1516 - "type": [ 1517 - "string", 1518 - "null" 1519 - ] 1477 + "type": ["string", "null"] 1520 1478 } 1521 1479 } 1522 1480 } 1523 1481 } 1524 - } 1482 + }
+925
pkg/c2patypes/c2patypes.go
··· 1 + // Code generated from JSON Schema using quicktype. DO NOT EDIT. 2 + // To parse and unparse this JSON data, add this code to your project and do: 3 + // 4 + // c2Patypes, err := UnmarshalC2Patypes(bytes) 5 + // bytes, err = c2Patypes.Marshal() 6 + 7 + package c2patypes 8 + 9 + import "bytes" 10 + import "errors" 11 + 12 + import "encoding/json" 13 + 14 + func UnmarshalC2Patypes(data []byte) (C2Patypes, error) { 15 + var r C2Patypes 16 + err := json.Unmarshal(data, &r) 17 + return r, err 18 + } 19 + 20 + func (r *C2Patypes) Marshal() ([]byte, error) { 21 + return json.Marshal(r) 22 + } 23 + 24 + type C2Patypes struct { 25 + Builder Builder `json:"builder"` 26 + ManifestDefinition ManifestDefinition `json:"manifest_definition"` 27 + Reader Reader `json:"reader"` 28 + } 29 + 30 + // Use a Builder to add a signed manifest to an asset. 31 + // 32 + // # Example: Building and signing a manifest 33 + // 34 + // ``` use c2pa::Result; use std::path::PathBuf; 35 + // 36 + // use c2pa::{create_signer, Builder, SigningAlg}; use serde::Serialize; use 37 + // serde_json::json; use tempfile::tempdir; 38 + // 39 + // #[derive(Serialize)] struct Test { my_tag: usize, } 40 + // 41 + // # fn main() -> Result<()> { #[cfg(feature = "file_io")] { let manifest_json = json!({ 42 + // "claim_generator_info": [ { "name": "c2pa_test", "version": "1.0.0" } ], "title": 43 + // "Test_Manifest" }).to_string(); 44 + // 45 + // let mut builder = Builder::from_json(&manifest_json)?; 46 + // builder.add_assertion("org.contentauth.test", &Test { my_tag: 42 })?; 47 + // 48 + // let source = PathBuf::from("tests/fixtures/C.jpg"); let dir = tempdir()?; let dest = 49 + // dir.path().join("test_file.jpg"); 50 + // 51 + // // Create a ps256 signer using certs and key files. TO DO: Update example. let 52 + // signcert_path = "tests/fixtures/certs/ps256.pub"; let pkey_path = 53 + // "tests/fixtures/certs/ps256.pem"; let signer = create_signer::from_files(signcert_path, 54 + // pkey_path, SigningAlg::Ps256, None)?; 55 + // 56 + // // embed a manifest using the signer builder.sign_file( signer.as_ref(), &source, 57 + // &dest)?; } # Ok(()) # } ``` 58 + type Builder struct { 59 + // A list of assertions 60 + Assertions []AssertionDefinition `json:"assertions,omitempty"` 61 + // Base path to search for resources. 62 + BasePath *string `json:"base_path"` 63 + // The type of builder being used. 64 + BuilderFlow *BuilderFlowUnion `json:"builder_flow"` 65 + // Claim Generator Info is always required with at least one entry 66 + ClaimGeneratorInfo []ClaimGeneratorInfo `json:"claim_generator_info,omitempty"` 67 + // The version of the claim. Defaults to 1. 68 + ClaimVersion *int64 `json:"claim_version"` 69 + // The format of the source file as a MIME type. 70 + Format *string `json:"format,omitempty"` 71 + // A List of ingredients 72 + Ingredients []Ingredient `json:"ingredients,omitempty"` 73 + // Instance ID from `xmpMM:InstanceID` in XMP metadata. 74 + InstanceID *string `json:"instance_id,omitempty"` 75 + // Allows you to pre-define the manifest label, which must be unique. Not intended for 76 + // general use. If not set, it will be assigned automatically. 77 + Label *string `json:"label"` 78 + // Optional manifest metadata. This will be deprecated in the future; not recommended to use. 79 + Metadata []AssertionMetadata `json:"metadata"` 80 + // If true, the manifest store will not be embedded in the asset on sign 81 + NoEmbed bool `json:"no_embed"` 82 + // A list of redactions - URIs to redacted assertions. 83 + Redactions []string `json:"redactions"` 84 + // Optional remote URL for the manifest 85 + RemoteURL *string `json:"remote_url"` 86 + // An optional ResourceRef to a thumbnail image that represents the asset that was signed. 87 + // Must be available when the manifest is signed. 88 + Thumbnail *IngredientResourceRef `json:"thumbnail"` 89 + // A human-readable title, generally source filename. 90 + Title *string `json:"title"` 91 + // Optional prefix added to the generated Manifest Label This is typically a reverse domain 92 + // name. 93 + Vendor *string `json:"vendor"` 94 + } 95 + 96 + // Defines an assertion that consists of a label that can be either a C2PA-defined assertion 97 + // label or a custom label in reverse domain format. 98 + type AssertionDefinition struct { 99 + Data interface{} `json:"data"` 100 + Label string `json:"label"` 101 + } 102 + 103 + type BuilderFlowClass struct { 104 + Create DigitalSourceType `json:"Create"` 105 + } 106 + 107 + // Description of the claim generator, or the software used in generating the claim. 108 + // 109 + // This structure is also used for actions softwareAgent 110 + type ClaimGeneratorInfo struct { 111 + // hashed URI to the icon (either embedded or remote) 112 + Icon *ResourceRef `json:"icon"` 113 + // A human readable string naming the claim_generator 114 + Name string `json:"name"` 115 + // A human readable string of the OS the claim generator is running on 116 + OperatingSystem *string `json:"operating_system"` 117 + // A human readable string of the product's version 118 + Version *string `json:"version"` 119 + } 120 + 121 + // A reference to a resource to be used in JSON serialization. 122 + // 123 + // The underlying data can be read as a stream via 124 + // [`Reader::resource_to_stream`][crate::Reader::resource_to_stream]. 125 + // 126 + // A `HashedUri` provides a reference to content available within the same manifest store. 127 + // 128 + // This is described in [§8.3, URI References], of the C2PA Technical Specification. 129 + // 130 + // [§8.3, URI References]: 131 + // https://c2pa.org/specifications/specifications/2.1/specs/C2PA_Specification.html#_uri_references 132 + type ResourceRef struct { 133 + // The algorithm used to hash the resource (if applicable). 134 + // 135 + // A string identifying the cryptographic hash algorithm used to compute the hash 136 + Alg *string `json:"alg"` 137 + // More detailed data types as defined in the C2PA spec. 138 + DataTypes []AssetType `json:"data_types"` 139 + // The mime type of the referenced resource. 140 + Format *string `json:"format,omitempty"` 141 + // The hash of the resource (if applicable). 142 + // 143 + // Byte string containing the hash value 144 + Hash *BasePath `json:"hash"` 145 + // A URI that identifies the resource as referenced from the manifest. 146 + // 147 + // This may be a JUMBF URI, a file path, a URL or any other string. Relative JUMBF URIs will 148 + // be resolved with the manifest label. Relative file paths will be resolved with the base 149 + // path if provided. 150 + Identifier *string `json:"identifier,omitempty"` 151 + // JUMBF URI reference 152 + URL *string `json:"url,omitempty"` 153 + } 154 + 155 + type AssetType struct { 156 + Type string `json:"type"` 157 + Version *string `json:"version"` 158 + } 159 + 160 + // An `Ingredient` is any external asset that has been used in the creation of an asset. 161 + type Ingredient struct { 162 + // The active manifest label (if one exists). 163 + // 164 + // If this ingredient has a [`ManifestStore`], this will hold the label of the active 165 + // [`Manifest`]. 166 + // 167 + // [`Manifest`]: crate::Manifest [`ManifestStore`]: crate::ManifestStore 168 + ActiveManifest *string `json:"active_manifest"` 169 + // A reference to the actual data of the ingredient. 170 + Data *IngredientResourceRef `json:"data"` 171 + // Additional information about the data's type to the ingredient V2 structure. 172 + DataTypes []AssetType `json:"data_types"` 173 + // Additional description of the ingredient. 174 + Description *string `json:"description"` 175 + // Document ID from `xmpMM:DocumentID` in XMP metadata. 176 + DocumentID *string `json:"document_id"` 177 + // The format of the source file as a MIME type. 178 + Format *string `json:"format"` 179 + // An optional hash of the asset to prevent duplicates. 180 + Hash *string `json:"hash"` 181 + // URI to an informational page about the ingredient or its data. 182 + InformationalURI *string `json:"informational_URI"` 183 + // Instance ID from `xmpMM:InstanceID` in XMP metadata. 184 + InstanceID *string `json:"instance_id"` 185 + // The ingredient's label as assigned in the manifest. 186 + Label *string `json:"label"` 187 + // A [`ManifestStore`] from the source asset extracted as a binary C2PA blob. 188 + // 189 + // [`ManifestStore`]: crate::ManifestStore 190 + ManifestData *IngredientResourceRef `json:"manifest_data"` 191 + // Any additional [`Metadata`] as defined in the C2PA spec. 192 + // 193 + // [`Metadata`]: crate::Metadata 194 + Metadata *AssertionMetadata `json:"metadata"` 195 + // URI from `dcterms:provenance` in XMP metadata. 196 + Provenance *string `json:"provenance"` 197 + // Set to `ParentOf` if this is the parent ingredient. 198 + // 199 + // There can only be one parent ingredient in the ingredients. 200 + Relationship *Relationship `json:"relationship,omitempty"` 201 + Resources *ResourceStore `json:"resources,omitempty"` 202 + // A thumbnail image capturing the visual state at the time of import. 203 + // 204 + // A tuple of thumbnail MIME format (for example `image/jpeg`) and binary bits of the image. 205 + Thumbnail *IngredientResourceRef `json:"thumbnail"` 206 + // A human-readable title, generally source filename. 207 + Title *string `json:"title"` 208 + // Validation results (Ingredient.V3) 209 + ValidationResults *ValidationResults `json:"validation_results"` 210 + // Validation status (Ingredient v1 & v2) 211 + ValidationStatus []ValidationStatus `json:"validation_status"` 212 + } 213 + 214 + // A reference to a resource to be used in JSON serialization. 215 + // 216 + // The underlying data can be read as a stream via 217 + // [`Reader::resource_to_stream`][crate::Reader::resource_to_stream]. 218 + type IngredientResourceRef struct { 219 + // The algorithm used to hash the resource (if applicable). 220 + Alg *string `json:"alg"` 221 + // More detailed data types as defined in the C2PA spec. 222 + DataTypes []AssetType `json:"data_types"` 223 + // The mime type of the referenced resource. 224 + Format string `json:"format"` 225 + // The hash of the resource (if applicable). 226 + Hash *string `json:"hash"` 227 + // A URI that identifies the resource as referenced from the manifest. 228 + // 229 + // This may be a JUMBF URI, a file path, a URL or any other string. Relative JUMBF URIs will 230 + // be resolved with the manifest label. Relative file paths will be resolved with the base 231 + // path if provided. 232 + Identifier string `json:"identifier"` 233 + } 234 + 235 + // A region of interest within an asset describing the change. 236 + // 237 + // This struct can be used from [`Action::changes`][crate::assertions::Action::changes] or 238 + // [`AssertionMetadata::region_of_interest`][crate::assertions::AssertionMetadata::region_of_interest]. 239 + type RegionOfInterest struct { 240 + // A free-text string. 241 + Description *string `json:"description"` 242 + // A free-text string representing a machine-readable, unique to this assertion, identifier 243 + // for the region. 244 + Identifier *string `json:"identifier"` 245 + // Additional information about the asset. 246 + Metadata *AssertionMetadata `json:"metadata"` 247 + // A free-text string representing a human-readable name for the region which might be used 248 + // in a user interface. 249 + Name *string `json:"name"` 250 + // A range describing the region of interest for the specific asset. 251 + Region []Range `json:"region"` 252 + // A value from our controlled vocabulary or an entity-specific value (e.g., 253 + // com.litware.coolArea) that represents the role of a region among other regions. 254 + Role *Role `json:"role"` 255 + // A value from a controlled vocabulary such as 256 + // <https://cv.iptc.org/newscodes/imageregiontype/> or an entity-specific value (e.g., 257 + // com.litware.newType) that represents the type of thing(s) depicted by a region. 258 + // 259 + // Note this field serializes/deserializes into the name `type`. 260 + Type *string `json:"type"` 261 + } 262 + 263 + // The AssertionMetadata structure can be used as part of other assertions or on its own to 264 + // reference others 265 + type AssertionMetadata struct { 266 + DataSource *DataSource `json:"dataSource"` 267 + DateTime *string `json:"dateTime"` 268 + Reference *HashedURI `json:"reference"` 269 + RegionOfInterest *RegionOfInterest `json:"regionOfInterest"` 270 + ReviewRatings []ReviewRating `json:"reviewRatings"` 271 + } 272 + 273 + // A spatial, temporal, frame, or textual range describing the region of interest. 274 + type Range struct { 275 + // A frame range. 276 + Frame *Frame `json:"frame"` 277 + // A item identifier. 278 + Item *Item `json:"item"` 279 + // A spatial range. 280 + Shape *Shape `json:"shape"` 281 + // A textual range. 282 + Text *Text `json:"text"` 283 + // A temporal range. 284 + Time *Time `json:"time"` 285 + // The type of range of interest. 286 + Type RangeType `json:"type"` 287 + } 288 + 289 + // A frame range representing starting and ending frames or pages. 290 + // 291 + // If both `start` and `end` are missing, the frame will span the entire asset. 292 + type Frame struct { 293 + // The end of the frame inclusive or the end of the asset if not present. 294 + End *int64 `json:"end"` 295 + // The start of the frame or the end of the asset if not present. 296 + // 297 + // The first frame/page starts at 0. 298 + Start *int64 `json:"start"` 299 + } 300 + 301 + // Description of the boundaries of an identified range. 302 + type Item struct { 303 + // The container-specific term used to identify items, such as "track_id" for MP4 or 304 + // "item_ID" for HEIF. 305 + Identifier string `json:"identifier"` 306 + // The value of the identifier, e.g. a value of "2" for an identifier of "track_id" would 307 + // imply track 2 of the asset. 308 + Value string `json:"value"` 309 + } 310 + 311 + // A spatial range representing rectangle, circle, or a polygon. 312 + type Shape struct { 313 + // The height of a rectnagle. 314 + // 315 + // This field can be ignored for circles and polygons. 316 + Height *float64 `json:"height"` 317 + // If the range is inside the shape. 318 + // 319 + // The default value is true. 320 + Inside *bool `json:"inside"` 321 + // THe origin of the coordinate in the shape. 322 + Origin Coordinate `json:"origin"` 323 + // The type of shape. 324 + Type ShapeType `json:"type"` 325 + // The type of unit for the shape range. 326 + Unit UnitType `json:"unit"` 327 + // The vertices of the polygon. 328 + // 329 + // This field can be ignored for rectangles and circles. 330 + Vertices []Coordinate `json:"vertices"` 331 + // The width for rectangles or diameter for circles. 332 + // 333 + // This field can be ignored for polygons. 334 + Width *float64 `json:"width"` 335 + } 336 + 337 + // THe origin of the coordinate in the shape. 338 + // 339 + // An x, y coordinate used for specifying vertices in polygons. 340 + type Coordinate struct { 341 + // The coordinate along the x-axis. 342 + X float64 `json:"x"` 343 + // The coordinate along the y-axis. 344 + Y float64 `json:"y"` 345 + } 346 + 347 + // A textual range representing multiple (possibly discontinuous) ranges of text. 348 + type Text struct { 349 + // The ranges of text to select. 350 + Selectors []TextSelectorRange `json:"selectors"` 351 + } 352 + 353 + // One or two [`TextSelector`][TextSelector] identifiying the range to select. 354 + type TextSelectorRange struct { 355 + // The end of the text range. 356 + End *TextSelector `json:"end"` 357 + // The start (or entire) text range. 358 + Selector TextSelector `json:"selector"` 359 + } 360 + 361 + // Selects a range of text via a fragment identifier. 362 + // 363 + // This is modeled after the W3C Web Annotation selector model. 364 + // 365 + // The start (or entire) text range. 366 + type TextSelector struct { 367 + // The end character offset or the end of the fragment if not present. 368 + End *int64 `json:"end"` 369 + // Fragment identifier as per RFC3023 (XML) or ISO 32000-2 (PDF), Annex O. 370 + Fragment string `json:"fragment"` 371 + // The start character offset or the start of the fragment if not present. 372 + Start *int64 `json:"start"` 373 + } 374 + 375 + // A temporal range representing a starting time to an ending time. 376 + type Time struct { 377 + // The end time or the end of the asset if not present. 378 + End *string `json:"end"` 379 + // The start time or the start of the asset if not present. 380 + Start *string `json:"start"` 381 + // The type of time. 382 + Type *TimeType `json:"type,omitempty"` 383 + } 384 + 385 + // A description of the source for assertion data 386 + type DataSource struct { 387 + // A list of [`Actor`]s associated with this source. 388 + Actors []Actor `json:"actors"` 389 + // A human-readable string giving details about the source of the assertion data. 390 + Details *string `json:"details"` 391 + // A value from among the enumerated list indicating the source of the assertion. 392 + Type string `json:"type"` 393 + } 394 + 395 + // Identifies a person responsible for an action. 396 + type Actor struct { 397 + // List of references to W3C Verifiable Credentials. 398 + Credentials []HashedURI `json:"credentials"` 399 + // An identifier for a human actor, used when the "type" is `humanEntry.identified`. 400 + Identifier *string `json:"identifier"` 401 + } 402 + 403 + // A `HashedUri` provides a reference to content available within the same manifest store. 404 + // 405 + // This is described in [§8.3, URI References], of the C2PA Technical Specification. 406 + // 407 + // [§8.3, URI References]: 408 + // https://c2pa.org/specifications/specifications/2.1/specs/C2PA_Specification.html#_uri_references 409 + type HashedURI struct { 410 + // A string identifying the cryptographic hash algorithm used to compute the hash 411 + Alg *string `json:"alg"` 412 + // Byte string containing the hash value 413 + Hash []int64 `json:"hash"` 414 + // JUMBF URI reference 415 + URL string `json:"url"` 416 + } 417 + 418 + // A rating on an Assertion. 419 + // 420 + // See 421 + // <https://c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_review_ratings>. 422 + type ReviewRating struct { 423 + Code *string `json:"code"` 424 + Explanation string `json:"explanation"` 425 + Value int64 `json:"value"` 426 + } 427 + 428 + // Resource store to contain binary objects referenced from JSON serializable structures 429 + // 430 + // container for binary assets (like thumbnails) 431 + type ResourceStore struct { 432 + BasePath *string `json:"base_path"` 433 + Label *string `json:"label"` 434 + Resources map[string][]int64 `json:"resources"` 435 + } 436 + 437 + // A map of validation results for a manifest store. 438 + // 439 + // The map contains the validation results for the active manifest and any ingredient 440 + // deltas. It is normal for there to be many 441 + type ValidationResults struct { 442 + ActiveManifest *StatusCodes `json:"activeManifest"` 443 + IngredientDeltas []IngredientDeltaValidationResult `json:"ingredientDeltas"` 444 + } 445 + 446 + // Contains a set of success, informational, and failure validation status codes. 447 + // 448 + // Validation results for the ingredient's active manifest 449 + type StatusCodes struct { 450 + Failure []ValidationStatus `json:"failure"` 451 + Informational []ValidationStatus `json:"informational"` 452 + Success []ValidationStatus `json:"success"` 453 + } 454 + 455 + // A `ValidationStatus` struct describes the validation status of a specific part of a 456 + // manifest. 457 + // 458 + // See 459 + // <https://c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_existing_manifests>. 460 + type ValidationStatus struct { 461 + Code string `json:"code"` 462 + Explanation *string `json:"explanation"` 463 + Success *bool `json:"success"` 464 + URL *string `json:"url"` 465 + } 466 + 467 + // Represents any changes or deltas between the current and previous validation results for 468 + // an ingredient's manifest. 469 + type IngredientDeltaValidationResult struct { 470 + // JUMBF URI reference to the ingredient assertion 471 + IngredientAssertionURI string `json:"ingredientAssertionURI"` 472 + // Validation results for the ingredient's active manifest 473 + ValidationDeltas StatusCodes `json:"validationDeltas"` 474 + } 475 + 476 + // Use a ManifestDefinition to define a manifest and to build a `ManifestStore`. A manifest 477 + // is a collection of ingredients and assertions used to define a claim that can be signed 478 + // and embedded into a file. 479 + type ManifestDefinition struct { 480 + // A list of assertions 481 + Assertions []AssertionDefinition `json:"assertions,omitempty"` 482 + // Claim Generator Info is always required with at least one entry 483 + ClaimGeneratorInfo []ClaimGeneratorInfo `json:"claim_generator_info,omitempty"` 484 + // The version of the claim. Defaults to 1. 485 + ClaimVersion *int64 `json:"claim_version"` 486 + // The format of the source file as a MIME type. 487 + Format *string `json:"format,omitempty"` 488 + // A List of ingredients 489 + Ingredients []Ingredient `json:"ingredients,omitempty"` 490 + // Instance ID from `xmpMM:InstanceID` in XMP metadata. 491 + InstanceID *string `json:"instance_id,omitempty"` 492 + // Allows you to pre-define the manifest label, which must be unique. Not intended for 493 + // general use. If not set, it will be assigned automatically. 494 + Label *string `json:"label"` 495 + // Optional manifest metadata. This will be deprecated in the future; not recommended to use. 496 + Metadata []AssertionMetadata `json:"metadata"` 497 + // A list of redactions - URIs to redacted assertions. 498 + Redactions []string `json:"redactions"` 499 + // An optional ResourceRef to a thumbnail image that represents the asset that was signed. 500 + // Must be available when the manifest is signed. 501 + Thumbnail *IngredientResourceRef `json:"thumbnail"` 502 + // A human-readable title, generally source filename. 503 + Title *string `json:"title"` 504 + // Optional prefix added to the generated Manifest Label This is typically a reverse domain 505 + // name. 506 + Vendor *string `json:"vendor"` 507 + } 508 + 509 + // Use a Reader to read and validate a manifest store. 510 + type Reader struct { 511 + // A label for the active (most recent) manifest in the store 512 + ActiveManifest *string `json:"active_manifest"` 513 + // A HashMap of Manifests 514 + Manifests map[string]Manifest `json:"manifests"` 515 + // ValidationStatus generated when loading the ManifestStore from an asset 516 + ValidationResults *ValidationResults `json:"validation_results"` 517 + // The validation state of the manifest store 518 + ValidationState *ValidationState `json:"validation_state"` 519 + // ValidationStatus generated when loading the ManifestStore from an asset 520 + ValidationStatus []ValidationStatus `json:"validation_status"` 521 + } 522 + 523 + // A Manifest represents all the information in a c2pa manifest 524 + type Manifest struct { 525 + // A list of assertions 526 + Assertions []ManifestAssertion `json:"assertions,omitempty"` 527 + // A User Agent formatted string identifying the software/hardware/system produced this 528 + // claim Spaces are not allowed in names, versions can be specified with product/1.0 syntax. 529 + ClaimGenerator *string `json:"claim_generator"` 530 + // A list of claim generator info data identifying the software/hardware/system produced 531 + // this claim. 532 + ClaimGeneratorInfo []ClaimGeneratorInfo `json:"claim_generator_info"` 533 + // A List of verified credentials 534 + Credentials []interface{} `json:"credentials"` 535 + // The format of the source file as a MIME type. 536 + Format *string `json:"format"` 537 + // A List of ingredients 538 + Ingredients []Ingredient `json:"ingredients,omitempty"` 539 + // Instance ID from `xmpMM:InstanceID` in XMP metadata. 540 + InstanceID *string `json:"instance_id,omitempty"` 541 + Label *string `json:"label"` 542 + // A list of user metadata for this claim. 543 + Metadata []AssertionMetadata `json:"metadata"` 544 + // A list of redactions - URIs to a redacted assertions 545 + Redactions []string `json:"redactions"` 546 + // container for binary assets (like thumbnails) 547 + Resources *ResourceStore `json:"resources,omitempty"` 548 + // Signature data (only used for reporting) 549 + SignatureInfo *SignatureInfo `json:"signature_info"` 550 + Thumbnail *IngredientResourceRef `json:"thumbnail"` 551 + // A human-readable title, generally source filename. 552 + Title *string `json:"title"` 553 + // Optional prefix added to the generated Manifest label. This is typically an internet 554 + // domain name for the vendor (i.e. `adobe`). 555 + Vendor *string `json:"vendor"` 556 + } 557 + 558 + // A labeled container for an Assertion value in a Manifest 559 + type ManifestAssertion struct { 560 + // The data of the assertion as Value 561 + Data interface{} `json:"data"` 562 + // There can be more than one assertion for any label 563 + Instance *int64 `json:"instance"` 564 + // The [ManifestAssertionKind] for this assertion (as stored in c2pa content) 565 + Kind *ManifestAssertionKind `json:"kind"` 566 + // An assertion label in reverse domain format 567 + Label string `json:"label"` 568 + } 569 + 570 + // Holds information about a signature 571 + type SignatureInfo struct { 572 + // Human-readable issuing authority for this signature. 573 + Alg *SigningAlg `json:"alg"` 574 + // The serial number of the certificate. 575 + CERTSerialNumber *string `json:"cert_serial_number"` 576 + // Human-readable issuing authority for this signature. 577 + Issuer *string `json:"issuer"` 578 + // Revocation status of the certificate. 579 + RevocationStatus *bool `json:"revocation_status"` 580 + // The time the signature was created. 581 + Time *string `json:"time"` 582 + } 583 + 584 + // Media whose digital content is effectively empty, such as a blank canvas or zero-length 585 + // video. 586 + // 587 + // Data that is the result of algorithmically using a model derived from sampled content and 588 + // data. Differs from 589 + // <http://cv.iptc.org/newscodes/digitalsourcetype/>trainedAlgorithmicMedia in that the 590 + // result isn’t a media type (e.g., image or video) but is a data format (e.g., CSV, pickle). 591 + type DigitalSourceType string 592 + 593 + const ( 594 + Empty DigitalSourceType = "Empty" 595 + TrainedAlgorithmicData DigitalSourceType = "TrainedAlgorithmicData" 596 + ) 597 + 598 + type BuilderFlowEnum string 599 + 600 + const ( 601 + Open BuilderFlowEnum = "Open" 602 + Update BuilderFlowEnum = "Update" 603 + ) 604 + 605 + // The type of shape. 606 + // 607 + // The type of shape for the range. 608 + // 609 + // A rectangle. 610 + // 611 + // A circle. 612 + // 613 + // A polygon. 614 + type ShapeType string 615 + 616 + const ( 617 + Circle ShapeType = "circle" 618 + Polygon ShapeType = "polygon" 619 + Rectangle ShapeType = "rectangle" 620 + ) 621 + 622 + // The type of unit for the shape range. 623 + // 624 + // The type of unit for the range. 625 + // 626 + // Use pixels. 627 + // 628 + // Use percentage. 629 + type UnitType string 630 + 631 + const ( 632 + Percent UnitType = "percent" 633 + Pixel UnitType = "pixel" 634 + ) 635 + 636 + // The type of time. 637 + // 638 + // Times are described using Normal Play Time (npt) as described in RFC 2326. 639 + type TimeType string 640 + 641 + const ( 642 + Npt TimeType = "npt" 643 + ) 644 + 645 + // The type of range of interest. 646 + // 647 + // The type of range for the region of interest. 648 + // 649 + // A spatial range, see [`Shape`] for more details. 650 + // 651 + // A temporal range, see [`Time`] for more details. 652 + // 653 + // A spatial range, see [`Frame`] for more details. 654 + // 655 + // A textual range, see [`Text`] for more details. 656 + // 657 + // A range identified by a specific identifier and value, see [`Item`] for more details. 658 + type RangeType string 659 + 660 + const ( 661 + Identified RangeType = "identified" 662 + RangeTypeFrame RangeType = "frame" 663 + Spatial RangeType = "spatial" 664 + Temporal RangeType = "temporal" 665 + Textual RangeType = "textual" 666 + ) 667 + 668 + // Arbitrary area worth identifying. 669 + // 670 + // This area is all that is left after a crop action. 671 + // 672 + // This area has had edits applied to it. 673 + // 674 + // The area where an ingredient was placed/added. 675 + // 676 + // Something in this area was redacted. 677 + // 678 + // Area specific to a subject (human or not). 679 + // 680 + // A range of information was removed/deleted. 681 + // 682 + // Styling was applied to this area. 683 + // 684 + // Invisible watermarking was applied to this area for the purpose of soft binding. 685 + type Role string 686 + 687 + const ( 688 + C2PaAreaOfInterest Role = "c2pa.areaOfInterest" 689 + C2PaCropped Role = "c2pa.cropped" 690 + C2PaDeleted Role = "c2pa.deleted" 691 + C2PaEdited Role = "c2pa.edited" 692 + C2PaPlaced Role = "c2pa.placed" 693 + C2PaRedacted Role = "c2pa.redacted" 694 + C2PaStyled Role = "c2pa.styled" 695 + C2PaSubjectArea Role = "c2pa.subjectArea" 696 + C2PaWatermarked Role = "c2pa.watermarked" 697 + ) 698 + 699 + // Set to `ParentOf` if this is the parent ingredient. 700 + // 701 + // There can only be one parent ingredient in the ingredients. 702 + // 703 + // The relationship of the ingredient to the current asset. 704 + // 705 + // The current asset is derived from this ingredient. 706 + // 707 + // The current asset is a part of this ingredient. 708 + // 709 + // The ingredient was used as an input to a computational process to create or modify the 710 + // asset. 711 + type Relationship string 712 + 713 + const ( 714 + ComponentOf Relationship = "componentOf" 715 + InputTo Relationship = "inputTo" 716 + ParentOf Relationship = "parentOf" 717 + ) 718 + 719 + // Assertions in C2PA can be stored in several formats 720 + type ManifestAssertionKind string 721 + 722 + const ( 723 + Binary ManifestAssertionKind = "Binary" 724 + Cbor ManifestAssertionKind = "Cbor" 725 + JSON ManifestAssertionKind = "Json" 726 + URI ManifestAssertionKind = "Uri" 727 + ) 728 + 729 + // ECDSA with SHA-256 730 + // 731 + // ECDSA with SHA-256 on secp256k1 curve 732 + // 733 + // ECDSA with SHA-384 734 + // 735 + // ECDSA with SHA-512 736 + // 737 + // RSASSA-PSS using SHA-256 and MGF1 with SHA-256 738 + // 739 + // RSASSA-PSS using SHA-384 and MGF1 with SHA-384 740 + // 741 + // RSASSA-PSS using SHA-512 and MGF1 with SHA-512 742 + // 743 + // Edwards-Curve DSA (Ed25519 instance only) 744 + type SigningAlg string 745 + 746 + const ( 747 + Ed25519 SigningAlg = "Ed25519" 748 + Es256 SigningAlg = "Es256" 749 + Es256K SigningAlg = "Es256K" 750 + Es384 SigningAlg = "Es384" 751 + Es512 SigningAlg = "Es512" 752 + Ps256 SigningAlg = "Ps256" 753 + Ps384 SigningAlg = "Ps384" 754 + Ps512 SigningAlg = "Ps512" 755 + ) 756 + 757 + // Errors were found in the manifest store. 758 + // 759 + // No errors were found in validation, but the active signature is not trusted. 760 + // 761 + // The manifest store is valid and the active signature is trusted. 762 + type ValidationState string 763 + 764 + const ( 765 + Invalid ValidationState = "Invalid" 766 + Trusted ValidationState = "Trusted" 767 + Valid ValidationState = "Valid" 768 + ) 769 + 770 + // The type of builder being used. 771 + type BuilderFlowUnion struct { 772 + BuilderFlowClass *BuilderFlowClass 773 + Enum *BuilderFlowEnum 774 + } 775 + 776 + func (x *BuilderFlowUnion) UnmarshalJSON(data []byte) error { 777 + x.BuilderFlowClass = nil 778 + x.Enum = nil 779 + var c BuilderFlowClass 780 + object, err := unmarshalUnion(data, nil, nil, nil, nil, false, nil, true, &c, false, nil, true, &x.Enum, true) 781 + if err != nil { 782 + return err 783 + } 784 + if object { 785 + x.BuilderFlowClass = &c 786 + } 787 + return nil 788 + } 789 + 790 + func (x *BuilderFlowUnion) MarshalJSON() ([]byte, error) { 791 + return marshalUnion(nil, nil, nil, nil, false, nil, x.BuilderFlowClass != nil, x.BuilderFlowClass, false, nil, x.Enum != nil, x.Enum, true) 792 + } 793 + 794 + type BasePath struct { 795 + IntegerArray []int64 796 + String *string 797 + } 798 + 799 + func (x *BasePath) UnmarshalJSON(data []byte) error { 800 + x.IntegerArray = nil 801 + object, err := unmarshalUnion(data, nil, nil, nil, &x.String, true, &x.IntegerArray, false, nil, false, nil, false, nil, true) 802 + if err != nil { 803 + return err 804 + } 805 + if object { 806 + } 807 + return nil 808 + } 809 + 810 + func (x *BasePath) MarshalJSON() ([]byte, error) { 811 + return marshalUnion(nil, nil, nil, x.String, x.IntegerArray != nil, x.IntegerArray, false, nil, false, nil, false, nil, true) 812 + } 813 + 814 + func unmarshalUnion(data []byte, pi **int64, pf **float64, pb **bool, ps **string, haveArray bool, pa interface{}, haveObject bool, pc interface{}, haveMap bool, pm interface{}, haveEnum bool, pe interface{}, nullable bool) (bool, error) { 815 + if pi != nil { 816 + *pi = nil 817 + } 818 + if pf != nil { 819 + *pf = nil 820 + } 821 + if pb != nil { 822 + *pb = nil 823 + } 824 + if ps != nil { 825 + *ps = nil 826 + } 827 + 828 + dec := json.NewDecoder(bytes.NewReader(data)) 829 + dec.UseNumber() 830 + tok, err := dec.Token() 831 + if err != nil { 832 + return false, err 833 + } 834 + 835 + switch v := tok.(type) { 836 + case json.Number: 837 + if pi != nil { 838 + i, err := v.Int64() 839 + if err == nil { 840 + *pi = &i 841 + return false, nil 842 + } 843 + } 844 + if pf != nil { 845 + f, err := v.Float64() 846 + if err == nil { 847 + *pf = &f 848 + return false, nil 849 + } 850 + return false, errors.New("Unparsable number") 851 + } 852 + return false, errors.New("Union does not contain number") 853 + case float64: 854 + return false, errors.New("Decoder should not return float64") 855 + case bool: 856 + if pb != nil { 857 + *pb = &v 858 + return false, nil 859 + } 860 + return false, errors.New("Union does not contain bool") 861 + case string: 862 + if haveEnum { 863 + return false, json.Unmarshal(data, pe) 864 + } 865 + if ps != nil { 866 + *ps = &v 867 + return false, nil 868 + } 869 + return false, errors.New("Union does not contain string") 870 + case nil: 871 + if nullable { 872 + return false, nil 873 + } 874 + return false, errors.New("Union does not contain null") 875 + case json.Delim: 876 + if v == '{' { 877 + if haveObject { 878 + return true, json.Unmarshal(data, pc) 879 + } 880 + if haveMap { 881 + return false, json.Unmarshal(data, pm) 882 + } 883 + return false, errors.New("Union does not contain object") 884 + } 885 + if v == '[' { 886 + if haveArray { 887 + return false, json.Unmarshal(data, pa) 888 + } 889 + return false, errors.New("Union does not contain array") 890 + } 891 + return false, errors.New("Cannot handle delimiter") 892 + } 893 + return false, errors.New("Cannot unmarshal union") 894 + } 895 + 896 + func marshalUnion(pi *int64, pf *float64, pb *bool, ps *string, haveArray bool, pa interface{}, haveObject bool, pc interface{}, haveMap bool, pm interface{}, haveEnum bool, pe interface{}, nullable bool) ([]byte, error) { 897 + if pi != nil { 898 + return json.Marshal(*pi) 899 + } 900 + if pf != nil { 901 + return json.Marshal(*pf) 902 + } 903 + if pb != nil { 904 + return json.Marshal(*pb) 905 + } 906 + if ps != nil { 907 + return json.Marshal(*ps) 908 + } 909 + if haveArray { 910 + return json.Marshal(pa) 911 + } 912 + if haveObject { 913 + return json.Marshal(pc) 914 + } 915 + if haveMap { 916 + return json.Marshal(pm) 917 + } 918 + if haveEnum { 919 + return json.Marshal(pe) 920 + } 921 + if nullable { 922 + return json.Marshal(nil) 923 + } 924 + return nil, errors.New("Union must not be null") 925 + }
+13 -2
pkg/cmd/streamplace.go
··· 3 3 import ( 4 4 "context" 5 5 "crypto" 6 + "encoding/json" 6 7 "errors" 7 8 "flag" 8 9 "fmt" ··· 24 25 "stream.place/streamplace/pkg/aqhttp" 25 26 "stream.place/streamplace/pkg/atproto" 26 27 "stream.place/streamplace/pkg/bus" 28 + c2patypes "stream.place/streamplace/pkg/c2patypes" 27 29 "stream.place/streamplace/pkg/crypto/signers" 28 30 "stream.place/streamplace/pkg/crypto/signers/eip712" 29 31 "stream.place/streamplace/pkg/director" ··· 56 58 if err != nil { 57 59 return err 58 60 } 59 - cert, _ := iroh_streamplace.PrintCert(bs) 60 - panic(cert) 61 + manifest, rustErr := iroh_streamplace.GetManifest(bs) 62 + if rustErr.AsError() != nil { 63 + return rustErr.AsError() 64 + } 65 + var mani c2patypes.Manifest 66 + err = json.Unmarshal([]byte(manifest), &mani) 67 + if err != nil { 68 + return err 69 + } 70 + fmt.Println(mani) 71 + os.Exit(0) 61 72 selfTest := len(os.Args) > 1 && os.Args[1] == "self-test" 62 73 err = media.RunSelfTest(context.Background()) 63 74 if err != nil {
+23
pkg/iroh/generated/iroh_streamplace/iroh_streamplace.go
··· 351 351 } 352 352 { 353 353 checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { 354 + return C.uniffi_iroh_streamplace_checksum_func_get_manifest() 355 + }) 356 + if checksum != 65147 { 357 + // If this happens try cleaning and rebuilding your project 358 + panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_func_get_manifest: UniFFI API checksum mismatch") 359 + } 360 + } 361 + { 362 + checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { 354 363 return C.uniffi_iroh_streamplace_checksum_func_print_cert() 355 364 }) 356 365 if checksum != 39427 { ··· 2109 2118 2110 2119 guard := handle.Value().(chan struct{}) 2111 2120 guard <- struct{}{} 2121 + } 2122 + 2123 + func GetManifest(data []byte) (string, *CertError) { 2124 + _uniffiRV, _uniffiErr := rustCallWithError[CertError](FfiConverterCertError{}, func(_uniffiStatus *C.RustCallStatus) RustBufferI { 2125 + return GoRustBuffer{ 2126 + inner: C.uniffi_iroh_streamplace_fn_func_get_manifest(FfiConverterBytesINSTANCE.Lower(data), _uniffiStatus), 2127 + } 2128 + }) 2129 + if _uniffiErr != nil { 2130 + var _uniffiDefaultValue string 2131 + return _uniffiDefaultValue, _uniffiErr 2132 + } else { 2133 + return FfiConverterStringINSTANCE.Lift(_uniffiRV), _uniffiErr 2134 + } 2112 2135 } 2113 2136 2114 2137 func PrintCert(data []byte) (string, *CertError) {
+11
pkg/iroh/generated/iroh_streamplace/iroh_streamplace.h
··· 571 571 uint64_t uniffi_iroh_streamplace_fn_method_sender_send(void* ptr, RustBuffer key, RustBuffer data 572 572 ); 573 573 #endif 574 + #ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_FUNC_GET_MANIFEST 575 + #define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_FUNC_GET_MANIFEST 576 + RustBuffer uniffi_iroh_streamplace_fn_func_get_manifest(RustBuffer data, RustCallStatus *out_status 577 + ); 578 + #endif 574 579 #ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_FUNC_PRINT_CERT 575 580 #define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_FUNC_PRINT_CERT 576 581 RustBuffer uniffi_iroh_streamplace_fn_func_print_cert(RustBuffer data, RustCallStatus *out_status ··· 854 859 #ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_COMPLETE_VOID 855 860 #define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_COMPLETE_VOID 856 861 void ffi_iroh_streamplace_rust_future_complete_void(uint64_t handle, RustCallStatus *out_status 862 + ); 863 + #endif 864 + #ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_FUNC_GET_MANIFEST 865 + #define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_FUNC_GET_MANIFEST 866 + uint16_t uniffi_iroh_streamplace_checksum_func_get_manifest(void 867 + 857 868 ); 858 869 #endif 859 870 #ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_FUNC_PRINT_CERT
+11
rust/iroh-streamplace/src/c2pa.rs
··· 24 24 } 25 25 Err(CertError::NoCertificateChainFound) 26 26 } 27 + 28 + #[uniffi::export] 29 + pub fn get_manifest(data: Vec<u8>) -> Result<String, CertError> { 30 + let reader = Reader::from_stream("video/mp4", Cursor::new(data)) 31 + .map_err(|e| CertError::C2paError(e.to_string()))?; 32 + // todo: add cawg certs here?? 33 + if let Some(manifest) = reader.active_manifest() { 34 + return Ok(manifest.to_string()); 35 + } 36 + Err(CertError::NoCertificateChainFound) 37 + }