Skip to content

Commit b34aa0d

Browse files
committed
Move example task code into includes to make reviewing by developers easier.
1 parent cb64e8d commit b34aa0d

24 files changed

+839
-774
lines changed

docs/tasks/build.mdx

Lines changed: 26 additions & 370 deletions
Large diffs are not rendered by default.

docs/tasks/get-resources.mdx

Lines changed: 20 additions & 194 deletions
Original file line numberDiff line numberDiff line change
@@ -6,213 +6,39 @@ title: Getting resources from a manifest
66
import Tabs from '@theme/Tabs';
77
import TabItem from '@theme/TabItem';
88

9-
Manifest data can include binary resources such as thumbnail and icon images which are referenced by JUMBF URIs in manifest data.
10-
11-
<Tabs groupId="programming-lang" >
12-
<TabItem value="js" label="JavaScript" default>
13-
14-
```js
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-
}
9+
import JSGetResources from './includes/_js-get-resources.md';
10+
import PythonGetResources from './includes/_python-get-resources.md';
11+
import NodeGetResources from './includes/_node-get-resources.md';
12+
import CppGetResources from './includes/_cpp-get-resources.md';
13+
import RustGetResources from './includes/_rust-get-resources.md';
7114

72-
document.querySelector('#results tbody')!.innerHTML = output.join('');
73-
})();
74-
```
75-
76-
</TabItem>
77-
78-
<TabItem value="python" label="Python">
79-
80-
Retrieve binary resources such as thumbnails from the manifest data, use the `resource_to_stream` or `resource_to_file` methods using the associated `identifier` field values and a `uri`.
81-
82-
NOTE: Need to add example of using `reader.resource_to_stream()`.
83-
84-
```python
85-
try:
86-
# Create a reader from a file path
87-
reader = c2pa.Reader.from_file("path/to/media_file.jpg")
88-
89-
# Get the active manifest.
90-
manifest = reader.get_active_manifest()
91-
if manifest != None:
15+
Manifest data can include binary resources such as thumbnail and icon images which are referenced by JUMBF URIs in manifest data.
9216

93-
# get the uri to the manifest's thumbnail and write it to a file
94-
uri = manifest["thumbnail"]["identifier"]
95-
reader.resource_to_file(uri, "thumbnail_v2.jpg")
17+
<Tabs groupId="programming-lang">
9618

97-
except Exception as err:
98-
print(err)
99-
```
19+
{' '}
20+
<TabItem value="js" label="JavaScript" default>
21+
<JSGetResources name="js-read" />
22+
</TabItem>
10023

24+
{' '}
25+
<TabItem value="python" label="Python" default>
26+
<PythonGetResources name="python-read" />
10127
</TabItem>
10228

29+
{' '}
10330
<TabItem value="node" label="Node.js">
104-
This is how to get resources from a manifest using Node.js.
31+
<NodeGetResources name="node-read" />
10532
</TabItem>
10633

34+
{' '}
10735
<TabItem value="cpp" label="C++">
108-
This is how to get resources from a manifest using C++.
109-
110-
```cpp
111-
string read_text_file(const fs::path &path)
112-
{
113-
ifstream file(path);
114-
if (!file.is_open())
115-
{
116-
throw runtime_error("Could not open file " + string(path));
117-
}
118-
string contents((istreambuf_iterator<char>(file)), istreambuf_iterator<char>());
119-
file.close();
120-
return contents.data();
121-
}
122-
123-
int main()
124-
{
125-
fs::path manifest_path = current_dir / "../tests/fixtures/training.json";
126-
//fs::path certs_path = current_dir / "../tests/fixtures/es256_certs.pem";
127-
//fs::path image_path = current_dir / "../tests/fixtures/A.jpg";
128-
fs::path output_path = current_dir / "../target/example/training.jpg";
129-
fs::path thumbnail_path = current_dir / "../target/example/thumbnail.jpg";
130-
131-
try
132-
{
133-
// load the manifest, certs, and private key
134-
/* Commenting out, because not part of resource reading
135-
string manifest_json = read_text_file(manifest_path).data();
136-
137-
string certs = read_text_file(certs_path).data();
138-
139-
// create a signer
140-
Signer signer = Signer(&test_signer, Es256, certs, "http://timestamp.digicert.com");
141-
142-
auto builder = Builder(manifest_json);
143-
auto manifest_data = builder.sign(image_path, output_path, signer);
144-
*/
145-
146-
// read the new manifest and display the JSON
147-
auto reader = Reader(output_path);
148-
149-
auto manifest_store_json = reader.json();
150-
cout << "The new manifest is " << manifest_store_json << endl;
151-
152-
// get the active manifest
153-
json manifest_store = json::parse(manifest_store_json);
154-
if (manifest_store.contains("active_manifest"))
155-
{
156-
string active_manifest = manifest_store["active_manifest"];
157-
json &manifest = manifest_store["manifests"][active_manifest];
158-
159-
string identifer = manifest["thumbnail"]["identifier"];
160-
161-
reader.get_resource(identifer, thumbnail_path);
162-
163-
cout << "thumbnail written to" << thumbnail_path << endl;
164-
}
165-
}
166-
catch (c2pa::Exception const &e)
167-
{
168-
cout << "C2PA Error: " << e.what() << endl;
169-
}
170-
catch (runtime_error const &e)
171-
{
172-
cout << "setup error" << e.what() << endl;
173-
}
174-
catch (json::parse_error const &e)
175-
{
176-
cout << "parse error " << e.what() << endl;
177-
}
178-
}
179-
```
180-
36+
<CppGetResources name="cpp-read" />
18137
</TabItem>
18238

39+
{' '}
18340
<TabItem value="rust" label="Rust">
184-
This is how to get resources using Rust.
185-
186-
This is from [`resource_to_stream`](https://docs.rs/c2pa/latest/c2pa/struct.Reader.html#method.resource_to_stream) API doc:
187-
188-
```rust
189-
use c2pa::Reader;
190-
let stream = std::io::Cursor::new(Vec::new());
191-
let reader = Reader::from_file("path/to/file.jpg").unwrap();
192-
let manifest = reader.active_manifest().unwrap();
193-
let uri = &manifest.thumbnail_ref().unwrap().identifier;
194-
let bytes_written = reader.resource_to_stream(uri, stream).unwrap();
195-
```
196-
197-
This is from [`c2pa-rs/examples/v2api.rs`](https://github.com/contentauth/c2pa-rs/blob/main/sdk/examples/v2api.rs#L138):
198-
199-
```rust
200-
let reader = Reader::from_stream(format, &mut dest)?;
201-
202-
// extract a thumbnail image from the ManifestStore
203-
let mut thumbnail = Cursor::new(Vec::new());
204-
if let Some(manifest) = reader.active_manifest() {
205-
if let Some(thumbnail_ref) = manifest.thumbnail_ref() {
206-
reader.resource_to_stream(&thumbnail_ref.identifier, &mut thumbnail)?;
207-
println!(
208-
"wrote thumbnail {} of size {}",
209-
thumbnail_ref.format,
210-
thumbnail.get_ref().len()
211-
);
212-
}
213-
}
214-
```
215-
41+
<RustGetResources name="rust-read" />
21642
</TabItem>
21743

21844
</Tabs>

docs/tasks/includes/_cpp-build.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
2+
```cpp
3+
const std::string manifest_json = R"{
4+
"claim_generator": "c2pa_c_test/0.1",
5+
"claim_generator_info": [
6+
{
7+
"name": "c2pa-c test",
8+
"version": "0.1"
9+
}
10+
],
11+
"assertions": [
12+
{
13+
"label": "c2pa.training-mining",
14+
"data": {
15+
"entries": {
16+
"c2pa.ai_generative_training": { "use": "notAllowed" },
17+
"c2pa.ai_inference": { "use": "notAllowed" },
18+
"c2pa.ai_training": { "use": "notAllowed" },
19+
"c2pa.data_mining": { "use": "notAllowed" }
20+
}
21+
}
22+
}
23+
]
24+
};
25+
26+
auto builder = Builder(manifest_json);
27+
28+
```
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
This is how to get resources from a manifest using C++.
2+
3+
```cpp
4+
string read_text_file(const fs::path &path)
5+
{
6+
ifstream file(path);
7+
if (!file.is_open())
8+
{
9+
throw runtime_error("Could not open file " + string(path));
10+
}
11+
string contents((istreambuf_iterator<char>(file)), istreambuf_iterator<char>());
12+
file.close();
13+
return contents.data();
14+
}
15+
16+
int main()
17+
{
18+
fs::path manifest_path = current_dir / "../tests/fixtures/training.json";
19+
//fs::path certs_path = current_dir / "../tests/fixtures/es256_certs.pem";
20+
//fs::path image_path = current_dir / "../tests/fixtures/A.jpg";
21+
fs::path output_path = current_dir / "../target/example/training.jpg";
22+
fs::path thumbnail_path = current_dir / "../target/example/thumbnail.jpg";
23+
24+
try
25+
{
26+
// load the manifest, certs, and private key
27+
/* Commenting out, because not part of resource reading
28+
string manifest_json = read_text_file(manifest_path).data();
29+
30+
string certs = read_text_file(certs_path).data();
31+
32+
// create a signer
33+
Signer signer = Signer(&test_signer, Es256, certs, "http://timestamp.digicert.com");
34+
35+
auto builder = Builder(manifest_json);
36+
auto manifest_data = builder.sign(image_path, output_path, signer);
37+
*/
38+
39+
// read the new manifest and display the JSON
40+
auto reader = Reader(output_path);
41+
42+
auto manifest_store_json = reader.json();
43+
cout << "The new manifest is " << manifest_store_json << endl;
44+
45+
// get the active manifest
46+
json manifest_store = json::parse(manifest_store_json);
47+
if (manifest_store.contains("active_manifest"))
48+
{
49+
string active_manifest = manifest_store["active_manifest"];
50+
json &manifest = manifest_store["manifests"][active_manifest];
51+
52+
string identifer = manifest["thumbnail"]["identifier"];
53+
54+
reader.get_resource(identifer, thumbnail_path);
55+
56+
cout << "thumbnail written to" << thumbnail_path << endl;
57+
}
58+
}
59+
catch (c2pa::Exception const &e)
60+
{
61+
cout << "C2PA Error: " << e.what() << endl;
62+
}
63+
catch (runtime_error const &e)
64+
{
65+
cout << "setup error" << e.what() << endl;
66+
}
67+
catch (json::parse_error const &e)
68+
{
69+
cout << "parse error " << e.what() << endl;
70+
}
71+
}
72+
```

docs/tasks/includes/_cpp-read.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
2+
Use the `read_file` function to read C2PA data from the specified file. This function examines the specified asset file for C2PA data and returns a JSON report if it finds any; it throws exceptions on errors. If there are validation errors, the report includes a `validation_status` field.
3+
4+
```cpp
5+
auto json_store = C2pa::read_file("<ASSET_FILE>", "<DATA_DIR>")
6+
```
7+
8+
Where:
9+
10+
- `<ASSET_FILE>`- The asset file to read.
11+
- `<DATA_DIR>` - Optional path to data output directory; If provided, the function extracts any binary resources, such as thumbnails, icons, and C2PA data into that directory. These files are referenced by the identifier fields in the manifest store report.
12+
13+
For example:
14+
15+
```cpp
16+
auto json_store = C2pa::read_file("work/media_file.jpg", "output/data_dir")
17+
```

docs/tasks/includes/_cpp-setup.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
To setup the C++ library:
2+
3+
```cpp
4+
#include <iostream>
5+
#include <fstream>
6+
#include <string>
7+
#include <vector>
8+
#include <stdexcept>
9+
#include <openssl/evp.h>
10+
#include <openssl/pem.h>
11+
#include <openssl/err.h>
12+
#include "c2pa.hpp"
13+
#include "test_signer.hpp"
14+
#include <nlohmann/json.hpp>
15+
16+
// this example uses nlohmann json for parsing the manifest
17+
using json = nlohmann::json;
18+
using namespace std;
19+
namespace fs = std::filesystem;
20+
using namespace c2pa;
21+
```

0 commit comments

Comments
 (0)