blob: 65366401c39b763db954b8827a239ab8abc30c9e [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/app_segment_creator.h"
#include <cstdint>
#include <string>
#include <vector>
#include "absl/status/status.h"
#include "absl/status/status_macros.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "utils/byte_readers.h"
#include "utils/byte_writers.h"
namespace credentio {
absl::StatusOr<std::vector<std::string>> CreateAppSegments(
AppSegmentParams params) {
absl::string_view payload(params.payload);
std::vector<std::string> segments;
ABSL_ASSIGN_OR_RETURN(uint32_t lbox, ConsumeUint<uint32_t>(&payload));
ABSL_ASSIGN_OR_RETURN(uint32_t tbox, ConsumeUint<uint32_t>(&payload));
uint64_t xlbox = 0;
if (lbox == 1) {
ABSL_ASSIGN_OR_RETURN(xlbox, ConsumeUint<uint64_t>(&payload));
}
if (!params.en.has_value()) {
params.en = 1;
}
uint32_t z = params.starting_z;
uint16_t base_le = sizeof(uint16_t) + // le
sizeof(uint16_t) + // cl
sizeof(uint16_t) + // en
sizeof(uint32_t) + // z
sizeof(uint32_t) + // lbox
sizeof(uint32_t) + // tbox
(lbox == 1 ? sizeof(uint64_t) : 0); // xlbox
if (params.max_size <= base_le) {
return absl::InvalidArgumentError(
"AppSegmentParams max_size must be strictly greater than base_le.");
}
uint16_t max_segment_size = params.max_size - base_le;
while (!payload.empty()) {
std::vector<uint8_t> bytes;
// The maximum size of the segment is params.max_size. The bytes vector
// also includes the 2-byte marker.
bytes.reserve(sizeof(uint16_t) + params.max_size);
// Add Marker
WriteUint16NetworkOrder(params.marker, &bytes);
uint16_t le =
base_le + (payload.length() < max_segment_size ? payload.length()
: max_segment_size);
// Add Size
WriteUint16NetworkOrder(le, &bytes);
// Add Extension Type
WriteUint16NetworkOrder(params.cl, &bytes);
// Add Identifier
WriteUint16NetworkOrder(*params.en, &bytes);
// Add Sequence Number
WriteUint32NetworkOrder(z, &bytes);
// Add LBox
WriteUint32NetworkOrder(lbox, &bytes);
// Add TBox
WriteUint32NetworkOrder(tbox, &bytes);
// Maybe Add XLBox
if (lbox == 1) {
WriteUint64NetworkOrder(xlbox, &bytes);
}
for (int i = 0; i < max_segment_size && !payload.empty(); ++i) {
// Will Always Contain at least one byte
ABSL_ASSIGN_OR_RETURN(auto byte, ConsumeUint<uint8_t>(&payload));
bytes.push_back(byte);
}
z = params.z_incrementer(z);
segments.push_back(std::string(bytes.begin(), bytes.end()));
}
return segments;
}
} // namespace credentio