blob: 28ab270be1b8b608c08bee722131bb9d549b78dc [file] [log] [blame]
// Copyright 2023 Google LLC
// SPDX-License-Identifier: BSD-2-Clause
#include <cstddef>
#include <cstdint>
#include <limits>
#include "avif/internal.h"
// From ../ext/ComplianceWarden/src/utils/
#include "box_reader_impl.h"
#include "spec.h"
bool checkComplianceStd(Box const & file, SpecDesc const * spec);
SpecDesc const * specFind(const char * name);
std::vector<SpecDesc const *> & g_allSpecs();
extern const SpecDesc * const globalSpecAvif;
extern const SpecDesc * const globalSpecAv1Hdr10plus;
extern const SpecDesc * const globalSpecHeif;
extern const SpecDesc * const globalSpecIsobmff;
extern const SpecDesc * const globalSpecMiaf;
extern "C" avifResult avifIsCompliant(const uint8_t * data, size_t size)
{
// See compliance_warden.sh.
if (g_allSpecs().empty()) {
registerSpec(globalSpecAvif);
registerSpec(globalSpecAv1Hdr10plus);
registerSpec(globalSpecHeif);
registerSpec(globalSpecIsobmff);
registerSpec(globalSpecMiaf);
}
// Inspired from ext/ComplianceWarden/src/app/cw.cpp
BoxReader topReader;
for (char sym : { 'f', 'i', 'l', 'e', '.', 'a', 'v', 'i', 'f' }) {
// Setting made-up file name (letter by letter).
topReader.myBox.syms.push_back({ "filename", static_cast<int64_t>(sym), 8 });
}
AVIF_CHECKERR(size <= std::numeric_limits<int>::max(), AVIF_RESULT_INVALID_ARGUMENT);
topReader.br = { const_cast<uint8_t *>(data), static_cast<int>(size) };
topReader.myBox.original = const_cast<uint8_t *>(data);
topReader.myBox.position = 0;
topReader.myBox.size = size;
topReader.myBox.fourcc = FOURCC("root");
topReader.specs = { specFind("avif") };
AVIF_CHECKERR(topReader.specs[0] != nullptr, AVIF_RESULT_UNKNOWN_ERROR);
auto parseFunc = getParseFunction(topReader.myBox.fourcc);
parseFunc(&topReader);
// gpac/ComplianceWarden will print the formatted result page to stdout, warnings and errors inclusive.
AVIF_CHECKERR(!checkComplianceStd(topReader.myBox, topReader.specs[0]), AVIF_RESULT_BMFF_PARSE_FAILED);
return AVIF_RESULT_OK;
}