blob: 62d68d82f49127ee897a99b06de01521a0778412 [file]
// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "formats/jpeg/testing/jumbf_creator.h"
#include <sys/stat.h>
#include <cstdint>
#include <optional>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "utils/byte_writers.h"
namespace credentio {
namespace {
std::string CreateJumbfDescriptionBox(const JumbfCreatorParams& params) {
std::vector<uint8_t> box;
// 4 bytes for Lbox
// 4 bytes for Tbox
// Maybe 8 bytes for XLBox (if forced)
// 8 bytes for UUID High
// 8 bytes for UUID Low
// 1 byte for Toggles
// X bytes for Label
// 1 byte for 0x00 terminator
// ---
// 26 + label.length() + 8?
uint32_t size = 26 + params.label.length() + (params.force_xlbox ? 8 : 0);
box.reserve(size);
uint32_t lbox = size;
std::optional<uint64_t> xlbox = std::nullopt;
if (params.force_xlbox) {
lbox = 1;
xlbox = static_cast<uint64_t>(size);
}
// Lbox
WriteUint32NetworkOrder(lbox, &box);
// Tbox
WriteUint32NetworkOrder(params.description_box_identifier, &box);
// Xlbox
if (xlbox.has_value()) {
WriteUint64NetworkOrder(*xlbox, &box);
}
// Type
WriteUint64NetworkOrder(params.uuid_high, &box);
WriteUint64NetworkOrder(params.uuid_low, &box);
// Toggles
box.push_back(params.toggles);
// Label
for (const auto& c : params.label) {
box.push_back(c);
}
box.push_back(params.label_terminator); // End of label
return std::string(box.begin(), box.end());
}
std::string CreateJumbfContentBox(absl::string_view payload) {
std::vector<uint8_t> box;
// 4 bytes for Lbox
// 4 bytes for Tbox
// ---
// 8 + payload.length()
uint32_t size = 8 + payload.size();
box.reserve(size);
// Lbox
WriteUint32NetworkOrder(size, &box);
// Tbox??
box.push_back('a');
box.push_back('a');
box.push_back('a');
box.push_back('a');
// Payload
for (const auto& c : payload) {
box.push_back(c);
}
return std::string(box.begin(), box.end());
}
} // namespace
std::string CreateJumbf(const JumbfCreatorParams& params) {
std::string description_box = CreateJumbfDescriptionBox(params);
std::string content_box = CreateJumbfContentBox(params.payload);
std::vector<uint8_t> box;
// 4 bytes for Lbox
// 4 bytes for Tbox
// Maybe 8 bytes for XLBox (if forced)
// Description Box
// Content Box
// ---
// 26 + label.length() + 8?
uint32_t size = 8 + (params.force_xlbox ? 8 : 0) + description_box.size() +
content_box.size();
box.reserve(size);
uint32_t lbox = size;
std::optional<uint64_t> xlbox = std::nullopt;
if (params.force_xlbox) {
lbox = 1;
xlbox = static_cast<uint64_t>(size);
}
// Lbox
WriteUint32NetworkOrder(lbox, &box);
// Tbox
WriteUint32NetworkOrder(params.super_box_identifier, &box);
// Xlbox
if (xlbox.has_value()) {
WriteUint64NetworkOrder(*xlbox, &box);
}
// Description Box
for (const auto& c : description_box) {
box.push_back(c);
}
// Content Box
for (const auto& c : content_box) {
box.push_back(c);
}
return std::string(box.begin(), box.end());
}
} // namespace credentio