There are 2 scenarios of this issue. I'm not sure if they share the same root cause, but since the scenarios are similar I'll include both here.
When using the modified example script, leaving the thumbnail_bytes empty will corrupt the 3rd multi-injected image, and no exception is raised during the process.
#!/usr/bin/python3
#
# Starling Hello World Example for multi-injection.
#
# This program will inject 3 CAI Stores.
#
# Usage
# $ python3 starling_multiple_injection.py <image-filepath>
#
# Verify
# 1. Go to https://verify.contentauthenticity.org/inspect
# 2. Drag and drop the generated image.
# 3. The webpage will show the CAI information.
import os
import sys
from cai.jumbf import json_to_bytes
from cai.starling import Starling
photo_filename = sys.argv[1]
# thumbnail_filename = sys.argv[1].replace('.jpg', '-thumbnail.jpg')
photo_bytes = open(photo_filename, 'rb').read()
# thumbnail_bytes = open(thumbnail_filename, 'rb').read()
location = ''
owner = ''
thumbnail_bytes = b''
public_key = ''
media_hash = ''
timestamp = ''
recorder1 = ''
recroder2 = ''
recorder3 = ''
metadata = [
{
'claim': {
'store_label': 'cb.Authmedia_1',
'recorder': recorder1,
},
'assertions': {
'adobe.asset.info': {
'type': '.json',
'data_bytes': json_to_bytes({
'title': photo_filename
})
},
'cai.location.broad': {
'type': '.json',
'data_bytes': json_to_bytes({
'location': location
})
},
'cai.rights': {
'type': '.json',
'data_bytes': json_to_bytes({
'copyright': owner
})
},
'cai.claim.thumbnail.jpg.jpg': {
'type': '.jpg',
'data_bytes': thumbnail_bytes
},
'cai.acquisition.thumbnail.jpg.jpg': {
'type': '.jpg',
'data_bytes': thumbnail_bytes
},
'starling.integrity.json': {
'type': '.json',
'data_bytes': json_to_bytes({
'starling:PublicKey': public_key,
'starling:MediaHash': media_hash,
'starling:MediaKey': '',
'starling:CaptureTimestamp': timestamp,
})
}
}
},
{
'claim': {
'store_label': 'cb.IOTAIntegrityChain_2',
'recorder': recroder2,
},
'assertions': {
'adobe.asset.info': {
'type': '.json',
'data_bytes': json_to_bytes({
'title': photo_filename
})
},
'cai.location.broad': {
'type': '.json',
'data_bytes': json_to_bytes({
'location': location
})
},
'cai.rights': {
'type': '.json',
'data_bytes': json_to_bytes({
'copyright': owner
})
},
'cai.claim.thumbnail.jpg.jpg': {
'type': '.jpg',
'data_bytes': thumbnail_bytes
},
'cai.acquisition.thumbnail.jpg.jpg': {
'type': '.jpg',
'data_bytes': thumbnail_bytes
},
'starling.integrity.json': {
'type': '.json',
'data_bytes': json_to_bytes({
'starling:PublicKey': public_key,
'starling:MediaHash': media_hash,
'starling:MediaKey': '',
'starling:CaptureTimestamp': timestamp
})
}
}
},
{
'claim': {
'store_label': 'cb.ThunderCoreNFTChain_3',
'recorder': recorder3,
},
'assertions': {
'adobe.asset.info': {
'type': '.json',
'data_bytes': json_to_bytes({
'title': photo_filename
})
},
'cai.location.broad': {
'type': '.json',
'data_bytes': json_to_bytes({
'location': location
})
},
'cai.rights': {
'type': '.json',
'data_bytes': json_to_bytes({
'copyright': owner
})
},
'cai.claim.thumbnail.jpg.jpg': {
'type': '.jpg',
'data_bytes': thumbnail_bytes
},
'cai.acquisition.thumbnail.jpg.jpg': {
'type': '.jpg',
'data_bytes': thumbnail_bytes
},
'starling.integrity.json': {
'type': '.json',
'data_bytes': json_to_bytes({
'starling:PublicKey': public_key,
'starling:MediaHash': media_hash,
'starling:CaptureTimestamp': timestamp,
})
}
}
},
]
# 1st CAI injection: Authmedia
# 2nd CAI injection: IOTA
# 3rd CAI injection: ThunderCore
for i in range(3):
starling = Starling(photo_bytes,
photo_filename,
metadata[i]['assertions'],
metadata[i]['claim']['store_label'],
metadata[i]['claim']['recorder'],
'',
'')
photo_bytes = starling.cai_injection()
# Save to file
fname, fext = os.path.splitext(photo_filename)
fpath = fname + '-cai-cai-cai' + fext
with open(fpath, 'wb') as f:
f.write(photo_bytes)
This thirdly injected image has valid thumbnail_bytes value (it can be seen on the Verify site), but it is still corrupted. I haven't figured out the reason yet.
There are 2 scenarios of this issue. I'm not sure if they share the same root cause, but since the scenarios are similar I'll include both here.
Scenario 1
When using the modified example script, leaving the thumbnail_bytes empty will corrupt the 3rd multi-injected image, and no exception is raised during the process.
Modified example script
This is a minimal modification base on https://github.com/numbersprotocol/starling-cai/blob/master/utils/starling_multiple_injection.py to reproduce the issue.
Run the script with
python3 <script-file> <jpeg-image-to-be-injected>Corrupted image
Scenario 2
This thirdly injected image has valid thumbnail_bytes value (it can be seen on the Verify site), but it is still corrupted. I haven't figured out the reason yet.
Corrupted image