Skip to main content

Viewing manifest data

Initializing the library

The way that you import wasmSrc and workerSrc varies depending on the build system you use. For more information, see Quick start.

Viewing manifest data

If the input provided to c2pa.read has a C2PA manifest and was processed without errors, the returned c2paReadResult contains a manifestStore.

The manifestStore object contains a few properties:

  • manifests: An object containing all manifests found in an asset, keyed by UUID.
  • activeManifest: A pointer to the latest manifest in the manifest store. Effectively the "parent" manifest, this is the likely starting point when inspecting an asset's C2PA data.
  • validationStatus: A list of any validation errors the library generated when processing an asset. See Validation for more information.

Manifest objects contain properties pertaining to an asset's provenance, along with convenient interfaces for accessing assertion data and generating a thumbnail.

Example

This example from the c2pa-js-examples repo demonstrates a basic workflow:

  • Reading an image.
  • Checking for the presence of a manifest store.
  • Displaying the data in the active manifest.

This example also features the use of the selectProducer selector function. See Selectors for more information.

To view and execute this example in a live code sandbox, see Sandbox: Viewing manifest data.

import { createC2pa, selectProducer } from 'c2pa';
import wasmSrc from 'c2pa/dist/assets/wasm/toolkit_bg.wasm?url';
import workerSrc from 'c2pa/dist/c2pa.worker.js?url';
import { parseISO } from 'date-fns';

const sampleImage =
'https://raw.githubusercontent.com/contentauth/c2pa-js/main/tools/testing/fixtures/images/CAICAI.jpg';

(async () => {
let output: string[] = [];

const c2pa = await createC2pa({
wasmSrc,
workerSrc,
});

const { manifestStore, source } = await c2pa.read(sampleImage);
const activeManifest = manifestStore?.activeManifest;
if (activeManifest) {
// Get thumbnail
// Note: You would normally call `dispose()` when working with a
// component-based UI library (e.g. on component un-mount)
// @ts-expect-error noUnusedLocals
const { url, dispose } = source.thumbnail.getUrl();

// Get properties
const properties: Record<string, string | undefined> = {
title: activeManifest.title,
format: activeManifest.format,
claimGenerator: activeManifest.claimGenerator.split('(')[0]?.trim(),
producer: selectProducer(activeManifest)?.name ?? 'Unknown',
thumbnail: `<img src="${url}" class="thumbnail" />`,
ingredients: (activeManifest.ingredients ?? [])
.map((i) => i.title)
.join(', '),
signatureIssuer: activeManifest.signatureInfo?.issuer,
signatureDate: activeManifest.signatureInfo?.time
? parseISO(activeManifest.signatureInfo.time).toString()
: 'No date available',
};

output = Object.keys(properties).map((key) => {
return `
<tr>
<td>${key}</td>
<td>${properties[key]}</td>
</tr>
`;
});
} else {
output.push(`
<tr>
<td colspan="2">No provenance data found</td>
</tr>
`);
}

document.querySelector('#results tbody')!.innerHTML = output.join('');
})();