Getting resources from a manifest
Manifest data can include binary resources such as thumbnail and icon images which are referenced by JUMBF URIs in manifest data.
- JavaScript
- Python
- Node.js
- C++
- Rust
The example below shows how to get resources from manifest data using the JavaScript library.
import { createC2pa } from '@contentauth/c2pa-web';
import wasmSrc from '@contentauth/c2pa-web/resources/c2pa.wasm?url';
const c2pa = createC2pa({ wasmSrc });
const response = await fetch(
'https://contentauth.github.io/example-assets/images/Firefly_tabby_cat.jpg'
);
const blob = await response.blob();
const reader = await c2pa.reader.fromBlob(blob.type, blob);
...
More TBD.
The example below shows how to get resources from manifest data using the Python library.
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.
NOTE: Need to add example of using reader.resource_to_stream().
# Import the C2PA Python package.
from c2pa import *
# Import standard general-purpose packages.
import os
import io
import logging
import json
try:
# Create a reader from a file path.
reader = c2pa.Reader.from_file("path/to/media_file.jpg")
# Get the active manifest.
manifest = reader.get_active_manifest()
if manifest != None:
# get the uri to the manifest's thumbnail and write it to a file.
uri = manifest["thumbnail"]["identifier"]
reader.resource_to_file(uri, "thumbnail_v2.jpg")
except Exception as err:
print(err)
The Node.js library is being revised. The documentation will be updated as soon as possible with the latest changes.
This is how to get resources from a manifest using C++.
#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;
}
}
The example below shows how to get resources from manifest data using the Rust library.
NOTE: Need to clarify if/how these two code examples work together.
This is from resource_to_stream API doc:
use c2pa::Reader;
#[cfg(feature = "file_io")]
{
let stream = std::io::Cursor::new(Vec::new());
let reader = Reader::from_file("path/to/file.jpg").unwrap();
let manifest = reader.active_manifest().unwrap();
let uri = &manifest.thumbnail_ref().unwrap().identifier;
let bytes_written = reader.resource_to_stream(uri, stream).unwrap();
}
This is from c2pa-rs/examples/v2api.rs:
use std::io::{Cursor, Seek};
use anyhow::Result;
use c2pa::{
crypto::raw_signature::SigningAlg, settings::Settings, validation_results::ValidationState,
Builder, CallbackSigner, Reader,
};
use serde_json::json;
let reader = Reader::from_stream(format, &mut dest)?;
// extract a thumbnail image from the ManifestStore
let mut thumbnail = Cursor::new(Vec::new());
if let Some(manifest) = reader.active_manifest() {
if let Some(thumbnail_ref) = manifest.thumbnail_ref() {
reader.resource_to_stream(&thumbnail_ref.identifier, &mut thumbnail)?;
println!(
"wrote thumbnail {} of size {}",
thumbnail_ref.format,
thumbnail.get_ref().len()
);
}
}