| // 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; |
| } |