Skip to content

Commit 4b9e7d5

Browse files
committed
Add Rust everywhere, add some examples, update .gitignore
1 parent 99fcfc9 commit 4b9e7d5

File tree

6 files changed

+212
-30
lines changed

6 files changed

+212
-30
lines changed

.gitignore

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,17 @@
88
.docusaurus
99
.cache-loader
1010
/docs/js-sdk/api
11-
/docs/c2patool
12-
/docs/rust-sdk
11+
/docs/c2patool/*.md
12+
/docs/c2patool/docs/*.md
13+
/docs/c2pa-node/*.md
14+
/docs/c2pa-node-example/*.md
15+
/docs/c2pa-node/docs/*.md
16+
/docs/c2pa-python/*.md
17+
/docs/c2pa-python/docs/*.md
18+
/docs/c2pa-c/*.md
19+
/docs/c2pa-c/docs/*.md
20+
/docs/rust-sdk/*.md
21+
/docs/rust-sdk/docs/*.md
1322
/docs/**/readme.md
1423

1524
# Misc
@@ -23,4 +32,4 @@ npm-debug.log*
2332
yarn-debug.log*
2433
yarn-error.log*
2534

26-
.dccache
35+
.dccache

docs/tasks/build.mdx

Lines changed: 121 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,136 @@
11
---
22
id: build
33
title: Building a manifest
4+
hide_table_of_contents: true
45
---
56

67
import Tabs from '@theme/Tabs';
78
import TabItem from '@theme/TabItem';
89

910
<Tabs groupId="programming-lang">
1011

11-
<TabItem value="python" label="Python" default>
12-
This is how to build a manifest using Python.
13-
</TabItem>
12+
<TabItem value="python" label="Python" default>
1413

15-
<TabItem value="cpp" label="C++">
16-
This is how to build a manifest using C++.
17-
</TabItem>
14+
```python
15+
try:
16+
# Define a function to sign the claim bytes
17+
# In this case we are using a pre-defined sign_ps256 method, passing in our private cert
18+
# Normally this cert would be kept safe in some other location
19+
def private_sign(data: bytes) -> bytes:
20+
return sign_ps256(data, "tests/fixtures/ps256.pem")
1821

19-
{' '}
20-
<TabItem value="node" label="Node.js">
21-
This is how to build a manifest using Node.js.
22-
</TabItem>
22+
# read our public certs into memory
23+
certs = open(data_dir + "ps256.pub", "rb").read()
24+
25+
# Create a signer from the private signer, certs and a time stamp service url
26+
signer = create_signer(private_sign, SigningAlg.PS256, certs, "http://timestamp.digicert.com")
27+
28+
# Create a builder add a thumbnail resource and an ingredient file.
29+
builder = Builder(manifest_json)
30+
31+
# Add the resource from a stream
32+
a_thumbnail_jpg_stream = open("tests/fixtures/A_thumbnail.jpg", "rb")
33+
builder.add_resource("image/jpeg", a_thumbnail_jpg_stream)
34+
35+
# Define an ingredient, in this case a parent ingredient named A.jpg, with a thumbnail
36+
ingredient_json = {
37+
"title": "A.jpg",
38+
"relationship": "parentOf", # "parentOf", "componentOf" or "inputTo"
39+
"thumbnail": {
40+
"identifier": "thumbnail",
41+
"format": "image/jpeg"
42+
}
43+
}
44+
45+
# Add the ingredient from a stream
46+
a_jpg_stream = open("tests/fixtures/A.jpg", "rb")
47+
builder.add_ingredient("image/jpeg", a_jpg_stream)
48+
49+
# At this point we could archive or unarchive our Builder to continue later.
50+
# In this example we use a bytearray for the archive stream.
51+
# all ingredients and resources will be saved in the archive
52+
archive = io.BytesIO(bytearray())
53+
builder.to_archive(archive)
54+
archive.seek()
55+
builder = builder.from_archive(archive)
56+
57+
# Sign the builder with a stream and output it to a stream
58+
# This returns the binary manifest data that could be uploaded to cloud storage.
59+
input_stream = open("tests/fixtures/A.jpg", "rb")
60+
output_stream = open("target/out.jpg", "wb")
61+
c2pa_data = builder.sign(signer, "image/jpeg", input_stream, output_stream)
62+
63+
except Exception as err:
64+
print(err)
65+
```
66+
67+
</TabItem>
68+
69+
<TabItem value="node" label="Node.js">
70+
71+
```ts
72+
import { ManifestBuilder } from 'c2pa-node';
73+
74+
const manifest = new ManifestBuilder({
75+
claim_generator: 'my-app/1.0.0',
76+
format: 'image/jpeg',
77+
title: 'node_test_local_signer.jpg',
78+
assertions: [
79+
{
80+
label: 'c2pa.actions',
81+
data: {
82+
actions: [
83+
{
84+
action: 'c2pa.created',
85+
},
86+
],
87+
},
88+
},
89+
{
90+
label: 'com.custom.my-assertion',
91+
data: {
92+
description: 'My custom test assertion',
93+
version: '1.0.0',
94+
},
95+
},
96+
],
97+
});
98+
```
99+
100+
</TabItem>
101+
102+
<TabItem value="cpp" label="C++">
103+
104+
```cpp
105+
const std::string manifest_json = R"{
106+
"claim_generator": "c2pa_c_test/0.1",
107+
"claim_generator_info": [
108+
{
109+
"name": "c2pa-c test",
110+
"version": "0.1"
111+
}
112+
],
113+
"assertions": [
114+
{
115+
"label": "c2pa.training-mining",
116+
"data": {
117+
"entries": {
118+
"c2pa.ai_generative_training": { "use": "notAllowed" },
119+
"c2pa.ai_inference": { "use": "notAllowed" },
120+
"c2pa.ai_training": { "use": "notAllowed" },
121+
"c2pa.data_mining": { "use": "notAllowed" }
122+
}
123+
}
124+
}
125+
]
126+
};
127+
128+
auto builder = Builder(manifest_json);
129+
130+
131+
```
132+
133+
</TabItem>
23134
24135
<TabItem value="rust" label="Rust">
25136
This is how to build a manifest using Rust.

docs/tasks/get-resources.mdx

Lines changed: 67 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,69 @@ Manifest data can include binary resources such as thumbnail and icon images whi
1010

1111
<Tabs groupId="programming-lang" >
1212
<TabItem value="js" label="JavaScript" default>
13-
This is how to get resources from a manifest using JavaScript.
13+
14+
```JavaScript
15+
import { createC2pa, selectProducer } from 'c2pa';
16+
import wasmSrc from 'c2pa/dist/assets/wasm/toolkit_bg.wasm?url';
17+
import workerSrc from 'c2pa/dist/c2pa.worker.js?url';
18+
import { parseISO } from 'date-fns';
19+
20+
const sampleImage =
21+
'https://raw.githubusercontent.com/contentauth/c2pa-js/main/tools/testing/fixtures/images/CAICAI.jpg';
22+
23+
(async () => {
24+
let output: string[] = [];
25+
26+
const c2pa = await createC2pa({
27+
wasmSrc,
28+
workerSrc,
29+
});
30+
31+
const { manifestStore, source } = await c2pa.read(sampleImage);
32+
const activeManifest = manifestStore?.activeManifest;
33+
if (activeManifest) {
34+
// Get thumbnail
35+
// Note: You would normally call `dispose()` when working with a
36+
// component-based UI library (e.g. on component un-mount)
37+
// @ts-expect-error noUnusedLocals
38+
const { url, dispose } = source.thumbnail.getUrl();
39+
40+
// Get properties
41+
const properties: Record<string, string | undefined> = {
42+
title: activeManifest.title,
43+
format: activeManifest.format,
44+
claimGenerator: activeManifest.claimGenerator.split('(')[0]?.trim(),
45+
producer: selectProducer(activeManifest)?.name ?? 'Unknown',
46+
thumbnail: `<img src="${url}" class="thumbnail" />`,
47+
ingredients: (activeManifest.ingredients ?? [])
48+
.map((i) => i.title)
49+
.join(', '),
50+
signatureIssuer: activeManifest.signatureInfo?.issuer,
51+
signatureDate: activeManifest.signatureInfo?.time
52+
? parseISO(activeManifest.signatureInfo.time).toString()
53+
: 'No date available',
54+
};
55+
56+
output = Object.keys(properties).map((key) => {
57+
return `
58+
<tr>
59+
<td>${key}</td>
60+
<td>${properties[key]}</td>
61+
</tr>
62+
`;
63+
});
64+
} else {
65+
output.push(`
66+
<tr>
67+
<td colspan="2">No provenance data found</td>
68+
</tr>
69+
`);
70+
}
71+
72+
document.querySelector('#results tbody')!.innerHTML = output.join('');
73+
})();
74+
```
75+
1476
</TabItem>
1577
1678
<TabItem value="python" label="Python">
@@ -38,16 +100,14 @@ except Exception as err:
38100
39101
</TabItem>
40102
41-
<TabItem value="cpp" label="C++">
42-
This is how to get resources from a manifest using C++.
43-
</TabItem>
44-
45-
{' '}
46103
<TabItem value="node" label="Node.js">
47104
This is how to get resources from a manifest using Node.js.
48105
</TabItem>
49106
50-
{' '}
107+
<TabItem value="cpp" label="C++">
108+
This is how to get resources from a manifest using C++.
109+
</TabItem>
110+
51111
<TabItem value="rust" label="Rust">
52112
This is how to get resources using Rust.
53113
</TabItem>

docs/tasks/sign.mdx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,16 @@ import TabItem from '@theme/TabItem';
1111
This is how to sign a manifest using Python.
1212
</TabItem>
1313

14-
<TabItem value="cpp" label="C++">
15-
This is how to sign a manifest using C++.
16-
</TabItem>
17-
1814
{' '}
15+
1916
<TabItem value="node" label="Node.js">
2017
This is how to sign a manifest using Node.js.
2118
</TabItem>
2219

20+
<TabItem value="cpp" label="C++">
21+
This is how to sign a manifest using C++.
22+
</TabItem>
23+
2324
<TabItem value="rust" label="Rust">
2425
This is how to sign a manifest using Rust.
2526
</TabItem>

docs/tasks/write.mdx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,16 @@ import TabItem from '@theme/TabItem';
1111
This is how to write a manifest using Python.
1212
</TabItem>
1313

14-
<TabItem value="cpp" label="C++">
15-
This is how to write a manifest using C++.
16-
</TabItem>
17-
1814
{' '}
1915
<TabItem value="node" label="Node.js">
2016
This is how to write a manifest using Node.js.
2117
</TabItem>
2218

19+
{' '}
20+
<TabItem value="cpp" label="C++">
21+
This is how to write a manifest using C++.
22+
</TabItem>
23+
2324
<TabItem value="rust" label="Rust">
2425
This is how to write a manifest using Rust.
2526
</TabItem>

sidebars.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,12 @@ const sidebars = {
9898
items: [
9999
{
100100
type: 'doc',
101-
id: 'c2patool/manifest',
101+
id: 'c2patool/docs/manifest',
102102
label: 'Using a manifest file',
103103
},
104104
{
105105
type: 'doc',
106-
id: 'c2patool/x_509',
106+
id: 'c2patool/docs/x_509',
107107
label: 'Creating and using a certificate',
108108
},
109109
{

0 commit comments

Comments
 (0)