diff --git a/cai/core.py b/cai/core.py index 3797a3c..4ed1499 100644 --- a/cai/core.py +++ b/cai/core.py @@ -87,11 +87,20 @@ def insert_xmp_key(data_bytes, store_label='cai/cb.starling_1'): metadata = pyexiv2.ImageMetadata.from_buffer(data_bytes) metadata.read() metadata['Xmp.dcterms.provenance'] = pyexiv2.XmpTag('Xmp.dcterms.provenance', - 'self#jumbf=' + store_label) + 'self#jumbf=cai/' + store_label) metadata.write() return metadata.buffer +def get_xmp_tag(data_bytes, tag='Xmp.dcterms.provenance'): + metadata = pyexiv2.ImageMetadata.from_buffer(data_bytes) + metadata.read() + if tag in metadata.xmp_keys: + return metadata[tag].raw_value + else: + return '' + + class CaiAssertionStore(SuperBox): def __init__(self, assertions): super(CaiAssertionStore, self).__init__() @@ -104,7 +113,8 @@ def __init__(self, assertions): class CaiClaim(SuperBox): def __init__(self, assertion_store, store_label='cb.starling_1', - recorder='Starling Capture using Numbers Protocol'): + recorder='Starling Capture using Numbers Protocol', + parent_claim=''): super(CaiClaim, self).__init__() self.description_box = DescriptionBox( content_type=Cai_content_types['claim'], @@ -113,13 +123,15 @@ def __init__(self, assertion_store, content_box.payload = json_to_bytes( self.create_claim(assertion_store, store_label=store_label, - recorder=recorder) + recorder=recorder, + parent_claim=parent_claim) ) self.content_boxes.append(content_box) def create_claim(self, assertion_store, store_label='cb.starling_1', - recorder='Starling Capture'): + recorder='Starling Capture', + parent_claim=''): '''Create a Claim JSON object ''' claim = {} @@ -134,6 +146,8 @@ def create_claim(self, assertion_store, for assertion in assertion_store.content_boxes ] claim['asset_hashes'] = Claim_asset_hashes_mockup + if parent_claim != '': + claim['parent_claim'] = parent_claim return claim @@ -186,13 +200,14 @@ class CaiStore(SuperBox): def __init__(self, label='cb.starling_1', assertions=[], recorder='Starling Capture', + parent_claim='', key=[]): super(CaiStore, self).__init__() self.description_box = DescriptionBox( content_type=Cai_content_types['store'], label=label) self.assertion_store = CaiAssertionStore(assertions) - self.claim = CaiClaim(self.assertion_store, recorder=recorder) + self.claim = CaiClaim(self.assertion_store, recorder=recorder, parent_claim=parent_claim) if len(key) == 0: self.signature = CaiClaimSignature() else: diff --git a/cai/starling.py b/cai/starling.py index 1f935c9..aba6d24 100644 --- a/cai/starling.py +++ b/cai/starling.py @@ -23,6 +23,7 @@ from cai.core import CaiStore from cai.jumbf import App11Box +from cai.core import get_xmp_tag from cai.core import insert_xmp_key from cai.jumbf import create_codestream_superbox from cai.jumbf import create_json_superbox @@ -83,6 +84,13 @@ def main(): print(assertion_labels) print(store_label) + # read media content if injection is enabled + with open(args.inject, 'rb') as f: + raw_bytes = f.read() + parent_claim = get_xmp_tag(raw_bytes) + print('parent_claim: ', parent_claim) + + # create CAI metadata assertions = [] for filepath, label in zip(assertion_filepaths, assertion_labels): with open(filepath, 'rb') as f: @@ -102,7 +110,11 @@ def main(): else: key = [] - cai_store = CaiStore(label=store_label, assertions=assertions, recorder=recorder, key=key) + cai_store = CaiStore(label=store_label, + assertions=assertions, + recorder=recorder, + parent_claim=parent_claim, + key=key) cai_claim_block = CaiClaimBlock() cai_claim_block.content_boxes.append(cai_store) cai_segment = App11Box() @@ -118,10 +130,6 @@ def main(): # inject CAI metadata if len(args.inject) > 0: fname, fext = os.path.splitext(args.inject) - - with open(args.inject, 'rb') as f: - raw_bytes = f.read() - fpath = fname + '-cai' + fext with open(fpath, 'wb') as f: data_bytes = raw_bytes[0:2] + cai_segment.convert_bytes() + raw_bytes[2:]