chromium/third_party/blink/renderer/platform/image-decoders/avif/gen_crabbyavif_wrapper.py

# Copyright 2024 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Script to generate crabbyavif wrapper using the libavif wrapper as the base.

When the libavif wrapper files (any of avif_image_decoder*) are changed, this
script must be run to update the crabbyavif wrappers
(crabbyavif_image_decoder*).
"""

import os
import re


def _read_file(filename):
    with open(filename) as file:
        return file.read()


def _write_file(filename, contents):
    with open(filename, "w") as file:
        file.write(contents)


def _apply_replacements(contents, replacements):
    for find, replace in replacements:
        contents = re.sub(find, replace, contents)
    return contents


_COMMON_REPLACEMENTS = (
    (r"Copyright 2020", "Copyright 2024"),
    (r"third_party/libavif/src", "third_party/crabbyavif/src"),
    (r"avif_image_decoder.h", "crabbyavif_image_decoder.h"),
    (r"AVIFImageDecoder", "CrabbyAVIFImageDecoder"),
    (r"AVIF_TRUE", "CRABBY_AVIF_TRUE"),
    (r"AVIF_FALSE", "CRABBY_AVIF_FALSE"),
    (r"AVIF_REPETITION_COUNT_", "CRABBY_AVIF_REPETITION_COUNT_"),
)

_NOTICE = """// WARNING: Auto-generated by gen_crabbyavif_wrapper.py.
// Do not modify manually.
"""


def _generate_crabbyavif_file(source_file, replacements):
    contents = _read_file(source_file)
    contents = _apply_replacements(contents, _COMMON_REPLACEMENTS)
    contents = _apply_replacements(contents, replacements)
    contents = contents.split("\n")
    # Copyright notice is 3 lines, insert the notice as the 4th line.
    contents.insert(3, _NOTICE)
    contents = "\n".join(contents)
    crabby_source_file = "crabby%(source_file)s" % locals()
    _write_file(crabby_source_file, contents)
    os.system("clang-format -style chromium -i %(crabby_source_file)s" %
              locals())


_HEADER_REPLACEMENTS = (
    (r"AVIF_AVIF_IMAGE_DECODER_H_", "AVIF_CRABBYAVIF_IMAGE_DECODER_H_"),
    (r"AVIF_PIXEL_FORMAT_NONE", "crabbyavif::AVIF_PIXEL_FORMAT_NONE"),
    # Functions
    (r"avifDecoderDestroy", "crabbyavif::crabby_avifDecoderDestroy"),
    (r"avifImageDestroy", "crabbyavif::crabby_avifImageDestroy"),
    # Types
    (r"avifIO", "crabbyavif::avifIO"),
    (r"avifPixelFormat", "crabbyavif::avifPixelFormat"),
    (r"avifROData", "crabbyavif::avifROData"),
    (r"avifResult", "crabbyavif::avifResult"),
    (r"\bavifDecoder\b", "crabbyavif::avifDecoder"),
    (r"\bavifImage\b", "crabbyavif::avifImage"),
)

_CC_REPLACEMENTS = (
    # Functions (to be namespaced and prefixed with "crabby_")
    (
        r"\bavifCropRectConvertCleanApertureBox\b",
        "crabbyavif::crabby_avifCropRectConvertCleanApertureBox",
    ),
    (r"\bavifDecoderCreate\b", "crabbyavif::crabby_avifDecoderCreate"),
    (
        r"\bavifDecoderDecodedRowCount\b",
        "crabbyavif::crabby_avifDecoderDecodedRowCount",
    ),
    (r"\bavifDecoderDestroy\b", "crabbyavif::crabby_avifDecoderDestroy"),
    (r"\bavifDecoderNthImage\b", "crabbyavif::crabby_avifDecoderNthImage"),
    (
        r"\bavifDecoderNthImageMaxExtent\b",
        "crabbyavif::crabby_avifDecoderNthImageMaxExtent",
    ),
    (
        r"\bavifDecoderNthImageMaxExtent\b",
        "crabbyavif::crabby_avifDecoderNthImageMaxExtent",
    ),
    (
        r"\bavifDecoderNthImageTiming\b",
        "crabbyavif::crabby_avifDecoderNthImageTiming",
    ),
    (r"\bavifDecoderParse\b", "crabbyavif::crabby_avifDecoderParse"),
    (r"\bavifDecoderSetIO\b", "crabbyavif::crabby_avifDecoderSetIO"),
    (r"\bavifDecoderSetSource\b", "crabbyavif::crabby_avifDecoderSetSource"),
    (
        r"\bavifGetPixelFormatInfo\b",
        "crabbyavif::crabby_avifGetPixelFormatInfo",
    ),
    (r"\bavifImageCreateEmpty\b", "crabbyavif::crabby_avifImageCreateEmpty"),
    (r"\bavifImageDestroy\b", "crabbyavif::crabby_avifImageDestroy"),
    (r"\bavifImageSetViewRect\b", "crabbyavif::crabby_avifImageSetViewRect"),
    (r"\bavifImageYUVToRGB\b", "crabbyavif::crabby_avifImageYUVToRGB"),
    (
        r"\bavifPeekCompatibleFileType\b",
        "crabbyavif::crabby_avifPeekCompatibleFileType",
    ),
    (
        r"\bavifRGBImageSetDefaults\b",
        "crabbyavif::crabby_avifRGBImageSetDefaults",
    ),
    (r"\bavifResultToString\b", "crabbyavif::crabby_avifResultToString"),
    # Symbols (to be namespaced).
    (r"avifBool\b", "crabbyavif::avifBool"),
    (r"avifColorPrimaries\b", "crabbyavif::avifColorPrimaries"),
    (r"avifCropRect\b", "crabbyavif::avifCropRect"),
    (r"avifDecoder\b", "crabbyavif::avifDecoder"),
    (r"avifDiagnostics\b", "crabbyavif::avifDiagnostics"),
    (r"avifExtent\b", "crabbyavif::avifExtent"),
    (r"avifGainMap\b", "crabbyavif::avifGainMap"),
    (r"avifGainMapMetadata\b", "crabbyavif::avifGainMapMetadata"),
    (r"avifIO\b", "crabbyavif::avifIO"),
    (r"avifImage\b", "crabbyavif::avifImage"),
    (r"avifImageTiming\b", "crabbyavif::avifImageTiming"),
    (r"avifMatrixCoefficients\b", "crabbyavif::avifMatrixCoefficients"),
    (r"avifPixelFormatInfo\b", "crabbyavif::avifPixelFormatInfo"),
    (r"avifRGBImage\b", "crabbyavif::avifRGBImage"),
    (r"avifROData\b", "crabbyavif::avifROData"),
    (r"avifRange\b", "crabbyavif::avifRange"),
    (r"avifResult\b", "crabbyavif::avifResult"),
    (
        r"avifTransferCharacteristics\b",
        "crabbyavif::avifTransferCharacteristics",
    ),
    (r"\bAVIF_", "crabbyavif::AVIF_"),
    (r"\bCRABBY_AVIF_", "crabbyavif::CRABBY_AVIF_"),
)

_TEST_REPLACEMENTS = (
    (r"\bAVIFValidImagesTest\b", "CrabbyAVIFValidImagesTest"),
    (r"\bAnimatedAVIFTests\b", "CrabbyAnimatedAVIFTests"),
    (r"\bStaticAVIFColorTests\b", "CrabbyStaticAVIFColorTests"),
    (r"\bStaticAVIFTests\b", "CrabbyStaticAVIFTests"),
)


def main():
    _generate_crabbyavif_file("avif_image_decoder.h", _HEADER_REPLACEMENTS)
    _generate_crabbyavif_file("avif_image_decoder.cc", _CC_REPLACEMENTS)
    _generate_crabbyavif_file("avif_image_decoder_test.cc", _TEST_REPLACEMENTS)
    _generate_crabbyavif_file("avif_image_decoder_fuzzer.cc", [])


if __name__ == "__main__":
    main()