Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
b12cdf9
Update sidebars.js
crandmck Nov 12, 2024
79228a2
Update manifest-tasks.mdx
crandmck Nov 12, 2024
fc7ecbe
Update manifest-tasks.mdx
crandmck Nov 12, 2024
c66b543
Update manifest-tasks.mdx
crandmck Nov 12, 2024
44a5dd5
Update manifest-tasks.mdx
crandmck Nov 12, 2024
305b50c
Move into separate tasks dir/sidebar branch
crandmck Nov 15, 2024
99fcfc9
Add rust
crandmck Nov 21, 2024
4b9e7d5
Add Rust everywhere, add some examples, update .gitignore
crandmck Dec 4, 2024
e854c70
Merge branch 'main' into manifest-tasks
crandmck Dec 4, 2024
131ac2b
Change page titles
crandmck Dec 5, 2024
27bd8a7
reword
crandmck Dec 19, 2024
fbc6051
Add setup
crandmck Dec 20, 2024
9aa2deb
Add more example code
crandmck Jan 10, 2025
0ec851f
Consolidate tasks, add cpp examples
crandmck Jan 14, 2025
6774774
Add Rust examples, fix syntax highlighting for Rust
crandmck Jan 15, 2025
cb64e8d
More example code
crandmck Jan 15, 2025
b34aa0d
Move example task code into includes to make reviewing by developers …
crandmck Feb 12, 2025
234b2d3
Fix spacing to avoid linting weirdness
crandmck Feb 12, 2025
7114864
Remove script committed by accident
crandmck Feb 12, 2025
0e9ccd1
Remove files from JS example repo
crandmck Feb 12, 2025
3b13602
Add examples to gitignore
crandmck Feb 12, 2025
171b336
Try again to remove spurious {' '} characters
crandmck Feb 12, 2025
640b70f
Merge branch 'main' into manifest-tasks
crandmck Feb 12, 2025
6cd1072
Update gitignore to properly ignore external examples pulled down by …
crandmck Feb 14, 2025
f346293
Add query param, other small edits
crandmck Feb 14, 2025
561ac54
Comments from Tania
crandmck Feb 14, 2025
00c6702
Comments from ahalle and tmathern
crandmck Feb 14, 2025
18d1c4b
Remove duplicate example
crandmck Feb 21, 2025
832b7e9
Eli comments
crandmck Feb 21, 2025
133d4ba
Fix code example
crandmck Feb 21, 2025
404b6b9
Remove content for Node.js and replace with WIP note
crandmck Mar 10, 2025
9ec18a5
Add Tania's comments for future reference
crandmck Mar 10, 2025
90333fe
Comments from Eli
crandmck Mar 10, 2025
92a8237
Remove Python streaming example code, just use file i/o.
crandmck Mar 13, 2025
ddd71f1
Kick to try to get a doc build
crandmck Jul 24, 2025
a90563d
Merge branch 'main' into manifest-tasks
crandmck Sep 18, 2025
44d3f61
Switch around section titles
crandmck Sep 18, 2025
c24e3f3
Remove setup page and include that code in each example instead
crandmck Sep 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,8 @@

# External files loaded by fetch-readmes script
/docs/js-sdk/api
/docs/js-sdk/examples/quickstart/*.ts
/docs/js-sdk/examples/view-manifest/*.ts
/docs/js-sdk/examples/view-manifest/*.html
/docs/c2pa-js/*.md
/docs/c2pa-js/docs/*.md
/docs/js-sdk/examples/*
/docs/js-sdk/examples/*
/docs/c2patool/*.md
/docs/c2patool/docs/*.md
/docs/c2pa-node/*.md
Expand Down Expand Up @@ -46,4 +43,4 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*

.dccache
.dccache
97 changes: 0 additions & 97 deletions docs/manifest/manifest-tasks.mdx

This file was deleted.

11 changes: 5 additions & 6 deletions docs/manifest/understanding.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
---
id: understanding-manifest
title: Working with manifests
title: Understanding manifests
---

## Understanding manifests

The concept of a _manifest_ is central to how Content Credentials work.

A collection of manifests (known as a _manifest store_) is attached to an asset. Each manifest contains information about the provenance of the asset. Creating or editing an asset using a C2PA-compliant device or tool (for example Adobe Photoshop) adds a new manifest to the manifest store.
A collection of manifests (known as a _manifest store_) is attached to an asset. Each manifest contains information about the provenance of the asset. Creating or editing an asset using a C2PA-compliant device or tool (for example, Adobe Photoshop) adds a new manifest to the manifest store.

The manifests in the manifest store are not ordered, but the most-recently added manifest is the _active manifest_. The active manifest has content bindings that can be validated with the asset—that is, it's hashed with the asset to ensure its validity.

Expand All @@ -21,17 +19,18 @@ A manifest store can be either:
In addition, an asset can have a [external manifest store](https://spec.c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_external_manifests), linked from the asset's metadata, as detailed in the [C2PA specification](https://spec.c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_embedding_a_reference_to_an_external_manifest). This is sometimes referred to as a _remote manifest_.

To determine if an asset has Content Credentials, the SDK checks for the presence of a manifest store in this order:

1. In the asset metadata
1. In a sidebar file.
1. In a remote manifest.

So, for example to see if `foo.jpg` has Content Credentials, the SDK first checks if there's a manifest store in the file itself, then looks for a sidecar file (`foo.c2pa` in the same directory), and finally looks in the asset's metadata for a reference to a remote manifest store.

:::info
Currently, only Adobe has implemented a Content Credentials cloud service to provide access to remote manifest stores, but in theory anyone could do so to provide a publicly-accessible network location for manifests.
Currently, only Adobe has implemented a Content Credentials cloud service to provide access to remote manifest stores, but in theory anyone could do so to provide a publicly-accessible network location for manifests.
:::

## Binary versus JSON manifest formats
## Binary versus JSON manifest

The manifest as described in the C2PA specification is a binary structure in JPEG universal metadata box format ([JUMBF](https://www.iso.org/standard/84635.html)) that can include JSON and binary data for things like encryption keys and thumbnail images.

Expand Down
50 changes: 50 additions & 0 deletions docs/tasks/build.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
id: build
title: Attaching and signing a manifest
hide_table_of_contents: true
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

import PythonBuild from './includes/_python-build.md';
/*
import NodeBuild from './includes/_node-build.md';
*/
import NodeWIP from './includes/_node-wip.md';
import CppBuild from './includes/_cpp-build.md';
import RustBuild from './includes/_rust-build.md';

<Tabs groupId="programming-lang" queryString="lang">

<TabItem value="js" label="JavaScript">

You can't currently attach a manifest to an asset and sign the claim using the JavaScript library. You need to use a language that runs on the "back-end," such as Python, Node.js, C++, or Rust.

</TabItem>

<TabItem value="python" label="Python" default>

<PythonBuild name="python-build" />

</TabItem>

<TabItem value="node" label="Node.js">

<NodeWIP name="node-build" />

</TabItem>

<TabItem value="cpp" label="C++">

<CppBuild name="cpp-build" />

</TabItem>

<TabItem value="rust" label="Rust">

<RustBuild name="rust-build" />

</TabItem>

</Tabs>
52 changes: 52 additions & 0 deletions docs/tasks/get-resources.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
id: get-resources
title: Getting resources from a manifest
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

import JSGetResources from './includes/_js-get-resources.md';
import PythonGetResources from './includes/_python-get-resources.md';
/*
import NodeGetResources from './includes/_node-get-resources.md';
*/
import NodeWIP from './includes/_node-wip.md';
import CppGetResources from './includes/_cpp-get-resources.md';
import RustGetResources from './includes/_rust-get-resources.md';

Manifest data can include binary resources such as thumbnail and icon images which are referenced by JUMBF URIs in manifest data.

<Tabs groupId="programming-lang" queryString="lang">

<TabItem value="js" label="JavaScript" default>

<JSGetResources name="js-read" />

</TabItem>

<TabItem value="python" label="Python" default>

<PythonGetResources name="python-read" />

</TabItem>

<TabItem value="node" label="Node.js">

<NodeWIP name="node-read" />

</TabItem>

<TabItem value="cpp" label="C++">

<CppGetResources name="cpp-read" />

</TabItem>

<TabItem value="rust" label="Rust">

<RustGetResources name="rust-read" />

</TabItem>

</Tabs>
43 changes: 43 additions & 0 deletions docs/tasks/includes/_cpp-build.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
This is an example of how to assign a manifest to an asset and sign the claim using C++:

```cpp
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <stdexcept>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include "c2pa.hpp"
#include "test_signer.hpp"

using namespace std;
namespace fs = std::filesystem;
using namespace c2pa;

const std::string manifest_json = R"{
"claim_generator": "c2pa_c_test/0.1",
"claim_generator_info": [
{
"name": "c2pa-c example",
"version": "0.1"
}
],
"assertions": [
{
"label": "cawg.training-mining",
"data": {
"entries": {
"cawg.ai_generative_training": { "use": "notAllowed" },
"cawg.ai_inference": { "use": "notAllowed" },
"cawg.ai_training": { "use": "notAllowed" },
"cawg.data_mining": { "use": "notAllowed" }
}
}
}
]
};

auto builder = Builder(manifest_json);
```
80 changes: 80 additions & 0 deletions docs/tasks/includes/_cpp-get-resources.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
This is how to get resources from a manifest using C++.

```cpp
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <stdexcept>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include "c2pa.hpp"
#include "test_signer.hpp"
#include <nlohmann/json.hpp>

// this example uses nlohmann json for parsing the manifest
using json = nlohmann::json;
using namespace std;
namespace fs = std::filesystem;
using namespace c2pa;

string read_text_file(const fs::path &path)
{
ifstream file(path);
if (!file.is_open())
{
throw runtime_error("Could not open file " + string(path));
}
string contents((istreambuf_iterator<char>(file)), istreambuf_iterator<char>());
file.close();
return contents.data();
}

int main()
{
fs::path manifest_path = current_dir / "../tests/fixtures/training.json";
//fs::path certs_path = current_dir / "../tests/fixtures/es256_certs.pem";
//fs::path image_path = current_dir / "../tests/fixtures/A.jpg";
fs::path output_path = current_dir / "../target/example/training.jpg";
fs::path thumbnail_path = current_dir / "../target/example/thumbnail.jpg";

try
{
// read the new manifest and display the JSON
auto reader = Reader(output_path);

auto manifest_store_json = reader.json();
cout << "The new manifest is " << manifest_store_json << endl;

// get the active manifest
json manifest_store = json::parse(manifest_store_json);
if (manifest_store.contains("active_manifest"))
{
string active_manifest = manifest_store["active_manifest"];
json &manifest = manifest_store["manifests"][active_manifest];

string identifer = manifest["thumbnail"]["identifier"];

reader.get_resource(identifer, thumbnail_path);

cout << "thumbnail written to" << thumbnail_path << endl;
}
}

catch (c2pa::Exception const &e)
{
cout << "C2PA Error: " << e.what() << endl;
}

catch (runtime_error const &e)
{
cout << "setup error" << e.what() << endl;
}

catch (json::parse_error const &e)
{
cout << "parse error " << e.what() << endl;
}
}
```
Loading