Skip to content

Commit 8c1a156

Browse files
committed
Support multiple JPEG XT Marker Segments.
If the total size of a CAI metadata > 65535 bytes, we need to split the CAI data to multiple segments. Signed-off-by: Bofu Chen (bafu) <bofu@numbersprotocol.io>
1 parent c861b94 commit 8c1a156

File tree

1 file changed

+37
-8
lines changed

1 file changed

+37
-8
lines changed

cai/jumbf.py

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -131,15 +131,44 @@ def __init__(self):
131131
def get_size(self):
132132
return len(self.convert_bytes())
133133

134+
def _split_payload(self):
135+
# Le (2B) + CI (2B) + En (4B) + Z (4B) + LBox (4B) + TBox (4B) = 18
136+
# Le_max = 65535
137+
# segment payload size = 65535 - 18 = 65517
138+
139+
segment_payload_size = 65517
140+
141+
# Preserve LBox and TBox
142+
# We will split original payload to multiple sub-payloads,
143+
# and add both LBox and TBox to each of the sub-payloads.
144+
lbox = self.payload[:4]
145+
tbox = self.payload[4:8]
146+
payload = self.payload[8:]
147+
148+
segment_superboxes = []
149+
while len(payload) > segment_payload_size:
150+
segment_superboxes.append(lbox + tbox + payload[:segment_payload_size])
151+
payload = payload[segment_payload_size:]
152+
segment_superboxes.append(lbox + tbox + payload)
153+
return segment_superboxes
154+
134155
def convert_bytes(self):
135-
marker = bytes.fromhex(self.marker)
136-
ci = bytes.fromhex(self.ci)
137-
en = self.en.to_bytes(2, byteorder='big')
138-
z = self.z.to_bytes(4, byteorder='big')
139-
# marker is not included
140-
length = 2 + len(ci) + len(en) + len(z) + len(self.payload)
141-
le = length.to_bytes(2, byteorder='big')
142-
return marker + le + ci + en + z + self.payload
156+
# Reminder: Superbox = LBox + TBox + Payload
157+
segment_superboxes = self._split_payload()
158+
total_bytes = b''
159+
self.z = 1
160+
for superbox in segment_superboxes:
161+
marker = bytes.fromhex(self.marker)
162+
ci = bytes.fromhex(self.ci)
163+
en = self.en.to_bytes(2, byteorder='big')
164+
z = self.z.to_bytes(4, byteorder='big')
165+
166+
# marker is not included
167+
length = 2 + len(ci) + len(en) + len(z) + len(superbox)
168+
le = length.to_bytes(2, byteorder='big')
169+
total_bytes += marker + le + ci + en + z + superbox
170+
self.z += 1
171+
return total_bytes
143172

144173

145174
def create_single_content_superbox(content=b'',

0 commit comments

Comments
 (0)